ActivityManagerService.java revision a5c336c32dae4586ff88d047a6def87b23d83d26
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.DEFER_RESUME;
371import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
372import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
373import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
374import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
375import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
376import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
377import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
378import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
379import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
380import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
381import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
382import static com.android.server.wm.AppTransition.TRANSIT_NONE;
383import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
384import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
385import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
386import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
387import static org.xmlpull.v1.XmlPullParser.START_TAG;
388
389public class ActivityManagerService extends IActivityManager.Stub
390        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
391
392    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
393    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
394    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
395    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
396    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
397    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
398    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
399    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
400    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
401    private static final String TAG_LRU = TAG + POSTFIX_LRU;
402    private static final String TAG_MU = TAG + POSTFIX_MU;
403    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
404    private static final String TAG_POWER = TAG + POSTFIX_POWER;
405    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
406    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
407    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
408    private static final String TAG_PSS = TAG + POSTFIX_PSS;
409    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
410    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
411    private static final String TAG_STACK = TAG + POSTFIX_STACK;
412    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
413    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
414    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
415    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
416    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
417
418    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
419    // here so that while the job scheduler can depend on AMS, the other way around
420    // need not be the case.
421    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
422
423    /** Control over CPU and battery monitoring */
424    // write battery stats every 30 minutes.
425    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
426    static final boolean MONITOR_CPU_USAGE = true;
427    // don't sample cpu less than every 5 seconds.
428    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
429    // wait possibly forever for next cpu sample.
430    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
431    static final boolean MONITOR_THREAD_CPU_USAGE = false;
432
433    // The flags that are set for all calls we make to the package manager.
434    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
435
436    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
437
438    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
439
440    // Amount of time after a call to stopAppSwitches() during which we will
441    // prevent further untrusted switches from happening.
442    static final long APP_SWITCH_DELAY_TIME = 5*1000;
443
444    // How long we wait for a launched process to attach to the activity manager
445    // before we decide it's never going to come up for real.
446    static final int PROC_START_TIMEOUT = 10*1000;
447    // How long we wait for an attached process to publish its content providers
448    // before we decide it must be hung.
449    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
450
451    // How long we will retain processes hosting content providers in the "last activity"
452    // state before allowing them to drop down to the regular cached LRU list.  This is
453    // to avoid thrashing of provider processes under low memory situations.
454    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
455
456    // How long we wait for a launched process to attach to the activity manager
457    // before we decide it's never going to come up for real, when the process was
458    // started with a wrapper for instrumentation (such as Valgrind) because it
459    // could take much longer than usual.
460    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
461
462    // How long to wait after going idle before forcing apps to GC.
463    static final int GC_TIMEOUT = 5*1000;
464
465    // The minimum amount of time between successive GC requests for a process.
466    static final int GC_MIN_INTERVAL = 60*1000;
467
468    // The minimum amount of time between successive PSS requests for a process.
469    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
470
471    // The minimum amount of time between successive PSS requests for a process
472    // when the request is due to the memory state being lowered.
473    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
474
475    // The rate at which we check for apps using excessive power -- 15 mins.
476    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
477
478    // The minimum sample duration we will allow before deciding we have
479    // enough data on wake locks to start killing things.
480    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
481
482    // The minimum sample duration we will allow before deciding we have
483    // enough data on CPU usage to start killing things.
484    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
485
486    // How long we allow a receiver to run before giving up on it.
487    static final int BROADCAST_FG_TIMEOUT = 10*1000;
488    static final int BROADCAST_BG_TIMEOUT = 60*1000;
489
490    // How long we wait until we timeout on key dispatching.
491    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
492
493    // How long we wait until we timeout on key dispatching during instrumentation.
494    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
495
496    // This is the amount of time an app needs to be running a foreground service before
497    // we will consider it to be doing interaction for usage stats.
498    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
499
500    // Maximum amount of time we will allow to elapse before re-reporting usage stats
501    // interaction with foreground processes.
502    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
503
504    // This is the amount of time we allow an app to settle after it goes into the background,
505    // before we start restricting what it can do.
506    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
507
508    // How long to wait in getAssistContextExtras for the activity and foreground services
509    // to respond with the result.
510    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
511
512    // How long top wait when going through the modern assist (which doesn't need to block
513    // on getting this result before starting to launch its UI).
514    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
515
516    // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result.
517    static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
518
519    // Maximum number of persisted Uri grants a package is allowed
520    static final int MAX_PERSISTED_URI_GRANTS = 128;
521
522    static final int MY_PID = Process.myPid();
523
524    static final String[] EMPTY_STRING_ARRAY = new String[0];
525
526    // How many bytes to write into the dropbox log before truncating
527    static final int DROPBOX_MAX_SIZE = 192 * 1024;
528    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
529    // as one line, but close enough for now.
530    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
531
532    // Access modes for handleIncomingUser.
533    static final int ALLOW_NON_FULL = 0;
534    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
535    static final int ALLOW_FULL_ONLY = 2;
536
537    // Necessary ApplicationInfo flags to mark an app as persistent
538    private static final int PERSISTENT_MASK =
539            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
540
541    // Intent sent when remote bugreport collection has been completed
542    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
543            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
544
545    // Used to indicate that an app transition should be animated.
546    static final boolean ANIMATE = true;
547
548    // Determines whether to take full screen screenshots
549    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
550    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
551
552    /** All system services */
553    SystemServiceManager mSystemServiceManager;
554
555    private Installer mInstaller;
556
557    /** Run all ActivityStacks through this */
558    final ActivityStackSupervisor mStackSupervisor;
559    private final KeyguardController mKeyguardController;
560
561    final ActivityStarter mActivityStarter;
562
563    final TaskChangeNotificationController mTaskChangeNotificationController;
564
565    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
566
567    public IntentFirewall mIntentFirewall;
568
569    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
570    // default action automatically.  Important for devices without direct input
571    // devices.
572    private boolean mShowDialogs = true;
573    private boolean mInVrMode = false;
574
575    // Whether we should use SCHED_FIFO for UI and RenderThreads.
576    private boolean mUseFifoUiScheduling = false;
577
578    BroadcastQueue mFgBroadcastQueue;
579    BroadcastQueue mBgBroadcastQueue;
580    // Convenient for easy iteration over the queues. Foreground is first
581    // so that dispatch of foreground broadcasts gets precedence.
582    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
583
584    BroadcastStats mLastBroadcastStats;
585    BroadcastStats mCurBroadcastStats;
586
587    BroadcastQueue broadcastQueueForIntent(Intent intent) {
588        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
589        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
590                "Broadcast intent " + intent + " on "
591                + (isFg ? "foreground" : "background") + " queue");
592        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
593    }
594
595    /**
596     * The last resumed activity. This is identical to the current resumed activity most
597     * of the time but could be different when we're pausing one activity before we resume
598     * another activity.
599     */
600    private ActivityRecord mLastResumedActivity;
601
602    /**
603     * If non-null, we are tracking the time the user spends in the currently focused app.
604     */
605    private AppTimeTracker mCurAppTimeTracker;
606
607    /**
608     * List of intents that were used to start the most recent tasks.
609     */
610    final RecentTasks mRecentTasks;
611
612    /**
613     * For addAppTask: cached of the last activity component that was added.
614     */
615    ComponentName mLastAddedTaskComponent;
616
617    /**
618     * For addAppTask: cached of the last activity uid that was added.
619     */
620    int mLastAddedTaskUid;
621
622    /**
623     * For addAppTask: cached of the last ActivityInfo that was added.
624     */
625    ActivityInfo mLastAddedTaskActivity;
626
627    /**
628     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
629     */
630    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
631
632    /**
633     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
634     */
635    String mDeviceOwnerName;
636
637    final UserController mUserController;
638
639    final AppErrors mAppErrors;
640
641    public boolean canShowErrorDialogs() {
642        return mShowDialogs && !mSleeping && !mShuttingDown
643                && !mKeyguardController.isKeyguardShowing();
644    }
645
646    private static final class PriorityState {
647        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
648        // the current thread is currently in. When it drops down to zero, we will no longer boost
649        // the thread's priority.
650        private int regionCounter = 0;
651
652        // The thread's previous priority before boosting.
653        private int prevPriority = Integer.MIN_VALUE;
654    }
655
656    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
657        @Override protected PriorityState initialValue() {
658            return new PriorityState();
659        }
660    };
661
662    static void boostPriorityForLockedSection() {
663        int tid = Process.myTid();
664        int prevPriority = Process.getThreadPriority(tid);
665        PriorityState state = sThreadPriorityState.get();
666        if (state.regionCounter == 0 && prevPriority > -2) {
667            state.prevPriority = prevPriority;
668            Process.setThreadPriority(tid, -2);
669        }
670        state.regionCounter++;
671    }
672
673    static void resetPriorityAfterLockedSection() {
674        PriorityState state = sThreadPriorityState.get();
675        state.regionCounter--;
676        if (state.regionCounter == 0 && state.prevPriority > -2) {
677            Process.setThreadPriority(Process.myTid(), state.prevPriority);
678        }
679    }
680
681    public class PendingAssistExtras extends Binder implements Runnable {
682        public final ActivityRecord activity;
683        public final Bundle extras;
684        public final Intent intent;
685        public final String hint;
686        public final IResultReceiver receiver;
687        public final int userHandle;
688        public boolean haveResult = false;
689        public Bundle result = null;
690        public AssistStructure structure = null;
691        public AssistContent content = null;
692        public Bundle receiverExtras;
693        public int flags;
694
695        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
696                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _flags,
697                int _userHandle) {
698            activity = _activity;
699            extras = _extras;
700            intent = _intent;
701            hint = _hint;
702            receiver = _receiver;
703            receiverExtras = _receiverExtras;
704            flags = _flags;
705            userHandle = _userHandle;
706        }
707        @Override
708        public void run() {
709            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710            synchronized (this) {
711                haveResult = true;
712                notifyAll();
713            }
714            pendingAssistExtrasTimedOut(this);
715        }
716    }
717
718    final ArrayList<PendingAssistExtras> mPendingAssistExtras
719            = new ArrayList<PendingAssistExtras>();
720
721    /**
722     * Process management.
723     */
724    final ProcessList mProcessList = new ProcessList();
725
726    /**
727     * All of the applications we currently have running organized by name.
728     * The keys are strings of the application package name (as
729     * returned by the package manager), and the keys are ApplicationRecord
730     * objects.
731     */
732    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
733
734    /**
735     * Tracking long-term execution of processes to look for abuse and other
736     * bad app behavior.
737     */
738    final ProcessStatsService mProcessStats;
739
740    /**
741     * The currently running isolated processes.
742     */
743    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
744
745    /**
746     * Counter for assigning isolated process uids, to avoid frequently reusing the
747     * same ones.
748     */
749    int mNextIsolatedProcessUid = 0;
750
751    /**
752     * The currently running heavy-weight process, if any.
753     */
754    ProcessRecord mHeavyWeightProcess = null;
755
756    /**
757     * All of the processes we currently have running organized by pid.
758     * The keys are the pid running the application.
759     *
760     * <p>NOTE: This object is protected by its own lock, NOT the global
761     * activity manager lock!
762     */
763    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
764
765    /**
766     * All of the processes that have been forced to be foreground.  The key
767     * is the pid of the caller who requested it (we hold a death
768     * link on it).
769     */
770    abstract class ForegroundToken implements IBinder.DeathRecipient {
771        int pid;
772        IBinder token;
773    }
774    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
775
776    /**
777     * List of records for processes that someone had tried to start before the
778     * system was ready.  We don't start them at that point, but ensure they
779     * are started by the time booting is complete.
780     */
781    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
782
783    /**
784     * List of persistent applications that are in the process
785     * of being started.
786     */
787    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
788
789    /**
790     * Processes that are being forcibly torn down.
791     */
792    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
793
794    /**
795     * List of running applications, sorted by recent usage.
796     * The first entry in the list is the least recently used.
797     */
798    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
799
800    /**
801     * Where in mLruProcesses that the processes hosting activities start.
802     */
803    int mLruProcessActivityStart = 0;
804
805    /**
806     * Where in mLruProcesses that the processes hosting services start.
807     * This is after (lower index) than mLruProcessesActivityStart.
808     */
809    int mLruProcessServiceStart = 0;
810
811    /**
812     * List of processes that should gc as soon as things are idle.
813     */
814    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
815
816    /**
817     * Processes we want to collect PSS data from.
818     */
819    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820
821    private boolean mBinderTransactionTrackingEnabled = false;
822
823    /**
824     * Last time we requested PSS data of all processes.
825     */
826    long mLastFullPssTime = SystemClock.uptimeMillis();
827
828    /**
829     * If set, the next time we collect PSS data we should do a full collection
830     * with data from native processes and the kernel.
831     */
832    boolean mFullPssPending = false;
833
834    /**
835     * This is the process holding what we currently consider to be
836     * the "home" activity.
837     */
838    ProcessRecord mHomeProcess;
839
840    /**
841     * This is the process holding the activity the user last visited that
842     * is in a different process from the one they are currently in.
843     */
844    ProcessRecord mPreviousProcess;
845
846    /**
847     * The time at which the previous process was last visible.
848     */
849    long mPreviousProcessVisibleTime;
850
851    /**
852     * Track all uids that have actively running processes.
853     */
854    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
855
856    /**
857     * This is for verifying the UID report flow.
858     */
859    static final boolean VALIDATE_UID_STATES = true;
860    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
861
862    /**
863     * Packages that the user has asked to have run in screen size
864     * compatibility mode instead of filling the screen.
865     */
866    final CompatModePackages mCompatModePackages;
867
868    /**
869     * Set of IntentSenderRecord objects that are currently active.
870     */
871    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
873
874    /**
875     * Fingerprints (hashCode()) of stack traces that we've
876     * already logged DropBox entries for.  Guarded by itself.  If
877     * something (rogue user app) forces this over
878     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879     */
880    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
882
883    /**
884     * Strict Mode background batched logging state.
885     *
886     * The string buffer is guarded by itself, and its lock is also
887     * used to determine if another batched write is already
888     * in-flight.
889     */
890    private final StringBuilder mStrictModeBuffer = new StringBuilder();
891
892    /**
893     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895     */
896    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
897
898    /**
899     * Resolver for broadcast intents to registered receivers.
900     * Holds BroadcastFilter (subclass of IntentFilter).
901     */
902    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904        @Override
905        protected boolean allowFilterResult(
906                BroadcastFilter filter, List<BroadcastFilter> dest) {
907            IBinder target = filter.receiverList.receiver.asBinder();
908            for (int i = dest.size() - 1; i >= 0; i--) {
909                if (dest.get(i).receiverList.receiver.asBinder() == target) {
910                    return false;
911                }
912            }
913            return true;
914        }
915
916        @Override
917        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919                    || userId == filter.owningUserId) {
920                return super.newResult(filter, match, userId);
921            }
922            return null;
923        }
924
925        @Override
926        protected BroadcastFilter[] newArray(int size) {
927            return new BroadcastFilter[size];
928        }
929
930        @Override
931        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932            return packageName.equals(filter.packageName);
933        }
934    };
935
936    /**
937     * State of all active sticky broadcasts per user.  Keys are the action of the
938     * sticky Intent, values are an ArrayList of all broadcasted intents with
939     * that action (which should usually be one).  The SparseArray is keyed
940     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941     * for stickies that are sent to all users.
942     */
943    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945
946    final ActiveServices mServices;
947
948    final static class Association {
949        final int mSourceUid;
950        final String mSourceProcess;
951        final int mTargetUid;
952        final ComponentName mTargetComponent;
953        final String mTargetProcess;
954
955        int mCount;
956        long mTime;
957
958        int mNesting;
959        long mStartTime;
960
961        // states of the source process when the bind occurred.
962        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963        long mLastStateUptime;
964        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965                - ActivityManager.MIN_PROCESS_STATE+1];
966
967        Association(int sourceUid, String sourceProcess, int targetUid,
968                ComponentName targetComponent, String targetProcess) {
969            mSourceUid = sourceUid;
970            mSourceProcess = sourceProcess;
971            mTargetUid = targetUid;
972            mTargetComponent = targetComponent;
973            mTargetProcess = targetProcess;
974        }
975    }
976
977    /**
978     * When service association tracking is enabled, this is all of the associations we
979     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
980     * -> association data.
981     */
982    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983            mAssociations = new SparseArray<>();
984    boolean mTrackingAssociations;
985
986    /**
987     * Backup/restore process management
988     */
989    String mBackupAppName = null;
990    BackupRecord mBackupTarget = null;
991
992    final ProviderMap mProviderMap;
993
994    /**
995     * List of content providers who have clients waiting for them.  The
996     * application is currently being launched and the provider will be
997     * removed from this list once it is published.
998     */
999    final ArrayList<ContentProviderRecord> mLaunchingProviders
1000            = new ArrayList<ContentProviderRecord>();
1001
1002    /**
1003     * File storing persisted {@link #mGrantedUriPermissions}.
1004     */
1005    private final AtomicFile mGrantFile;
1006
1007    /** XML constants used in {@link #mGrantFile} */
1008    private static final String TAG_URI_GRANTS = "uri-grants";
1009    private static final String TAG_URI_GRANT = "uri-grant";
1010    private static final String ATTR_USER_HANDLE = "userHandle";
1011    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014    private static final String ATTR_TARGET_PKG = "targetPkg";
1015    private static final String ATTR_URI = "uri";
1016    private static final String ATTR_MODE_FLAGS = "modeFlags";
1017    private static final String ATTR_CREATED_TIME = "createdTime";
1018    private static final String ATTR_PREFIX = "prefix";
1019
1020    /**
1021     * Global set of specific {@link Uri} permissions that have been granted.
1022     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023     * to {@link UriPermission#uri} to {@link UriPermission}.
1024     */
1025    @GuardedBy("this")
1026    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028
1029    public static class GrantUri {
1030        public final int sourceUserId;
1031        public final Uri uri;
1032        public boolean prefix;
1033
1034        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035            this.sourceUserId = sourceUserId;
1036            this.uri = uri;
1037            this.prefix = prefix;
1038        }
1039
1040        @Override
1041        public int hashCode() {
1042            int hashCode = 1;
1043            hashCode = 31 * hashCode + sourceUserId;
1044            hashCode = 31 * hashCode + uri.hashCode();
1045            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1046            return hashCode;
1047        }
1048
1049        @Override
1050        public boolean equals(Object o) {
1051            if (o instanceof GrantUri) {
1052                GrantUri other = (GrantUri) o;
1053                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054                        && prefix == other.prefix;
1055            }
1056            return false;
1057        }
1058
1059        @Override
1060        public String toString() {
1061            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062            if (prefix) result += " [prefix]";
1063            return result;
1064        }
1065
1066        public String toSafeString() {
1067            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068            if (prefix) result += " [prefix]";
1069            return result;
1070        }
1071
1072        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074                    ContentProvider.getUriWithoutUserId(uri), false);
1075        }
1076    }
1077
1078    CoreSettingsObserver mCoreSettingsObserver;
1079
1080    FontScaleSettingObserver mFontScaleSettingObserver;
1081
1082    private final class FontScaleSettingObserver extends ContentObserver {
1083        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084
1085        public FontScaleSettingObserver() {
1086            super(mHandler);
1087            ContentResolver resolver = mContext.getContentResolver();
1088            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1089        }
1090
1091        @Override
1092        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093            if (mFontScaleUri.equals(uri)) {
1094                updateFontScaleIfNeeded(userId);
1095            }
1096        }
1097    }
1098
1099    /**
1100     * Thread-local storage used to carry caller permissions over through
1101     * indirect content-provider access.
1102     */
1103    private class Identity {
1104        public final IBinder token;
1105        public final int pid;
1106        public final int uid;
1107
1108        Identity(IBinder _token, int _pid, int _uid) {
1109            token = _token;
1110            pid = _pid;
1111            uid = _uid;
1112        }
1113    }
1114
1115    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1116
1117    /**
1118     * All information we have collected about the runtime performance of
1119     * any user id that can impact battery performance.
1120     */
1121    final BatteryStatsService mBatteryStatsService;
1122
1123    /**
1124     * Information about component usage
1125     */
1126    UsageStatsManagerInternal mUsageStatsService;
1127
1128    /**
1129     * Access to DeviceIdleController service.
1130     */
1131    DeviceIdleController.LocalService mLocalDeviceIdleController;
1132
1133    /**
1134     * Information about and control over application operations
1135     */
1136    final AppOpsService mAppOpsService;
1137
1138    /** Current sequencing integer of the configuration, for skipping old configurations. */
1139    private int mConfigurationSeq;
1140
1141    /**
1142     * Temp object used when global and/or display override configuration is updated. It is also
1143     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1144     * anyone...
1145     */
1146    private Configuration mTempConfig = new Configuration();
1147
1148    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1149            new UpdateConfigurationResult();
1150    private static final class UpdateConfigurationResult {
1151        // Configuration changes that were updated.
1152        int changes;
1153        // If the activity was relaunched to match the new configuration.
1154        boolean activityRelaunched;
1155
1156        void reset() {
1157            changes = 0;
1158            activityRelaunched = false;
1159        }
1160    }
1161
1162    boolean mSuppressResizeConfigChanges;
1163
1164    /**
1165     * Hardware-reported OpenGLES version.
1166     */
1167    final int GL_ES_VERSION;
1168
1169    /**
1170     * List of initialization arguments to pass to all processes when binding applications to them.
1171     * For example, references to the commonly used services.
1172     */
1173    HashMap<String, IBinder> mAppBindArgs;
1174    HashMap<String, IBinder> mIsolatedAppBindArgs;
1175
1176    /**
1177     * Temporary to avoid allocations.  Protected by main lock.
1178     */
1179    final StringBuilder mStringBuilder = new StringBuilder(256);
1180
1181    /**
1182     * Used to control how we initialize the service.
1183     */
1184    ComponentName mTopComponent;
1185    String mTopAction = Intent.ACTION_MAIN;
1186    String mTopData;
1187
1188    volatile boolean mProcessesReady = false;
1189    volatile boolean mSystemReady = false;
1190    volatile boolean mOnBattery = false;
1191    volatile int mFactoryTest;
1192
1193    @GuardedBy("this") boolean mBooting = false;
1194    @GuardedBy("this") boolean mCallFinishBooting = false;
1195    @GuardedBy("this") boolean mBootAnimationComplete = false;
1196    @GuardedBy("this") boolean mLaunchWarningShown = false;
1197    @GuardedBy("this") boolean mCheckedForSetup = false;
1198
1199    Context mContext;
1200
1201    /**
1202     * The time at which we will allow normal application switches again,
1203     * after a call to {@link #stopAppSwitches()}.
1204     */
1205    long mAppSwitchesAllowedTime;
1206
1207    /**
1208     * This is set to true after the first switch after mAppSwitchesAllowedTime
1209     * is set; any switches after that will clear the time.
1210     */
1211    boolean mDidAppSwitch;
1212
1213    /**
1214     * Last time (in realtime) at which we checked for power usage.
1215     */
1216    long mLastPowerCheckRealtime;
1217
1218    /**
1219     * Last time (in uptime) at which we checked for power usage.
1220     */
1221    long mLastPowerCheckUptime;
1222
1223    /**
1224     * Set while we are wanting to sleep, to prevent any
1225     * activities from being started/resumed.
1226     *
1227     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1228     *
1229     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1230     * while in the sleep state until there is a pending transition out of sleep, in which case
1231     * mSleeping is set to false, and remains false while awake.
1232     *
1233     * Whether mSleeping can quickly toggled between true/false without the device actually
1234     * display changing states is undefined.
1235     */
1236    private boolean mSleeping = false;
1237
1238    /**
1239     * The process state used for processes that are running the top activities.
1240     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1241     */
1242    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1243
1244    /**
1245     * Set while we are running a voice interaction.  This overrides
1246     * sleeping while it is active.
1247     */
1248    private IVoiceInteractionSession mRunningVoice;
1249
1250    /**
1251     * For some direct access we need to power manager.
1252     */
1253    PowerManagerInternal mLocalPowerManager;
1254
1255    /**
1256     * We want to hold a wake lock while running a voice interaction session, since
1257     * this may happen with the screen off and we need to keep the CPU running to
1258     * be able to continue to interact with the user.
1259     */
1260    PowerManager.WakeLock mVoiceWakeLock;
1261
1262    /**
1263     * State of external calls telling us if the device is awake or asleep.
1264     */
1265    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1266
1267    /**
1268     * A list of tokens that cause the top activity to be put to sleep.
1269     * They are used by components that may hide and block interaction with underlying
1270     * activities.
1271     */
1272    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1273
1274    /**
1275     * Set if we are shutting down the system, similar to sleeping.
1276     */
1277    boolean mShuttingDown = false;
1278
1279    /**
1280     * Current sequence id for oom_adj computation traversal.
1281     */
1282    int mAdjSeq = 0;
1283
1284    /**
1285     * Current sequence id for process LRU updating.
1286     */
1287    int mLruSeq = 0;
1288
1289    /**
1290     * Keep track of the non-cached/empty process we last found, to help
1291     * determine how to distribute cached/empty processes next time.
1292     */
1293    int mNumNonCachedProcs = 0;
1294
1295    /**
1296     * Keep track of the number of cached hidden procs, to balance oom adj
1297     * distribution between those and empty procs.
1298     */
1299    int mNumCachedHiddenProcs = 0;
1300
1301    /**
1302     * Keep track of the number of service processes we last found, to
1303     * determine on the next iteration which should be B services.
1304     */
1305    int mNumServiceProcs = 0;
1306    int mNewNumAServiceProcs = 0;
1307    int mNewNumServiceProcs = 0;
1308
1309    /**
1310     * Allow the current computed overall memory level of the system to go down?
1311     * This is set to false when we are killing processes for reasons other than
1312     * memory management, so that the now smaller process list will not be taken as
1313     * an indication that memory is tighter.
1314     */
1315    boolean mAllowLowerMemLevel = false;
1316
1317    /**
1318     * The last computed memory level, for holding when we are in a state that
1319     * processes are going away for other reasons.
1320     */
1321    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1322
1323    /**
1324     * The last total number of process we have, to determine if changes actually look
1325     * like a shrinking number of process due to lower RAM.
1326     */
1327    int mLastNumProcesses;
1328
1329    /**
1330     * The uptime of the last time we performed idle maintenance.
1331     */
1332    long mLastIdleTime = SystemClock.uptimeMillis();
1333
1334    /**
1335     * Total time spent with RAM that has been added in the past since the last idle time.
1336     */
1337    long mLowRamTimeSinceLastIdle = 0;
1338
1339    /**
1340     * If RAM is currently low, when that horrible situation started.
1341     */
1342    long mLowRamStartTime = 0;
1343
1344    /**
1345     * For reporting to battery stats the current top application.
1346     */
1347    private String mCurResumedPackage = null;
1348    private int mCurResumedUid = -1;
1349
1350    /**
1351     * For reporting to battery stats the apps currently running foreground
1352     * service.  The ProcessMap is package/uid tuples; each of these contain
1353     * an array of the currently foreground processes.
1354     */
1355    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1356            = new ProcessMap<ArrayList<ProcessRecord>>();
1357
1358    /**
1359     * This is set if we had to do a delayed dexopt of an app before launching
1360     * it, to increase the ANR timeouts in that case.
1361     */
1362    boolean mDidDexOpt;
1363
1364    /**
1365     * Set if the systemServer made a call to enterSafeMode.
1366     */
1367    boolean mSafeMode;
1368
1369    /**
1370     * If true, we are running under a test environment so will sample PSS from processes
1371     * much more rapidly to try to collect better data when the tests are rapidly
1372     * running through apps.
1373     */
1374    boolean mTestPssMode = false;
1375
1376    String mDebugApp = null;
1377    boolean mWaitForDebugger = false;
1378    boolean mDebugTransient = false;
1379    String mOrigDebugApp = null;
1380    boolean mOrigWaitForDebugger = false;
1381    boolean mAlwaysFinishActivities = false;
1382    boolean mForceResizableActivities;
1383    boolean mSupportsMultiWindow;
1384    boolean mSupportsSplitScreenMultiWindow;
1385    boolean mSupportsFreeformWindowManagement;
1386    boolean mSupportsPictureInPicture;
1387    boolean mSupportsLeanbackOnly;
1388    IActivityController mController = null;
1389    boolean mControllerIsAMonkey = false;
1390    String mProfileApp = null;
1391    ProcessRecord mProfileProc = null;
1392    String mProfileFile;
1393    ParcelFileDescriptor mProfileFd;
1394    int mSamplingInterval = 0;
1395    boolean mAutoStopProfiler = false;
1396    int mProfileType = 0;
1397    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1398    String mMemWatchDumpProcName;
1399    String mMemWatchDumpFile;
1400    int mMemWatchDumpPid;
1401    int mMemWatchDumpUid;
1402    String mTrackAllocationApp = null;
1403    String mNativeDebuggingApp = null;
1404
1405    final long[] mTmpLong = new long[2];
1406
1407    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1408
1409    static final class ProcessChangeItem {
1410        static final int CHANGE_ACTIVITIES = 1<<0;
1411        static final int CHANGE_PROCESS_STATE = 1<<1;
1412        int changes;
1413        int uid;
1414        int pid;
1415        int processState;
1416        boolean foregroundActivities;
1417    }
1418
1419    static final class UidObserverRegistration {
1420        final int uid;
1421        final String pkg;
1422        final int which;
1423        final int cutpoint;
1424
1425        final SparseIntArray lastProcStates;
1426
1427        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1428            uid = _uid;
1429            pkg = _pkg;
1430            which = _which;
1431            cutpoint = _cutpoint;
1432            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1433                lastProcStates = new SparseIntArray();
1434            } else {
1435                lastProcStates = null;
1436            }
1437        }
1438    }
1439
1440    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1441    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1442
1443    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1444    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1445
1446    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1447    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1448
1449    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1450    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1451
1452    /**
1453     * Runtime CPU use collection thread.  This object's lock is used to
1454     * perform synchronization with the thread (notifying it to run).
1455     */
1456    final Thread mProcessCpuThread;
1457
1458    /**
1459     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1460     * Must acquire this object's lock when accessing it.
1461     * NOTE: this lock will be held while doing long operations (trawling
1462     * through all processes in /proc), so it should never be acquired by
1463     * any critical paths such as when holding the main activity manager lock.
1464     */
1465    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1466            MONITOR_THREAD_CPU_USAGE);
1467    final AtomicLong mLastCpuTime = new AtomicLong(0);
1468    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1469    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1470
1471    long mLastWriteTime = 0;
1472
1473    /**
1474     * Used to retain an update lock when the foreground activity is in
1475     * immersive mode.
1476     */
1477    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1478
1479    /**
1480     * Set to true after the system has finished booting.
1481     */
1482    boolean mBooted = false;
1483
1484    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1485    int mProcessLimitOverride = -1;
1486
1487    WindowManagerService mWindowManager;
1488    final ActivityThread mSystemThread;
1489
1490    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1491        final ProcessRecord mApp;
1492        final int mPid;
1493        final IApplicationThread mAppThread;
1494
1495        AppDeathRecipient(ProcessRecord app, int pid,
1496                IApplicationThread thread) {
1497            if (DEBUG_ALL) Slog.v(
1498                TAG, "New death recipient " + this
1499                + " for thread " + thread.asBinder());
1500            mApp = app;
1501            mPid = pid;
1502            mAppThread = thread;
1503        }
1504
1505        @Override
1506        public void binderDied() {
1507            if (DEBUG_ALL) Slog.v(
1508                TAG, "Death received in " + this
1509                + " for thread " + mAppThread.asBinder());
1510            synchronized(ActivityManagerService.this) {
1511                appDiedLocked(mApp, mPid, mAppThread, true);
1512            }
1513        }
1514    }
1515
1516    static final int SHOW_ERROR_UI_MSG = 1;
1517    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1518    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1519    static final int UPDATE_CONFIGURATION_MSG = 4;
1520    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1521    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1522    static final int SERVICE_TIMEOUT_MSG = 12;
1523    static final int UPDATE_TIME_ZONE = 13;
1524    static final int SHOW_UID_ERROR_UI_MSG = 14;
1525    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1526    static final int PROC_START_TIMEOUT_MSG = 20;
1527    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1528    static final int KILL_APPLICATION_MSG = 22;
1529    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1530    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1531    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1532    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1533    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1534    static final int CLEAR_DNS_CACHE_MSG = 28;
1535    static final int UPDATE_HTTP_PROXY_MSG = 29;
1536    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1537    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1538    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1539    static final int REPORT_MEM_USAGE_MSG = 33;
1540    static final int REPORT_USER_SWITCH_MSG = 34;
1541    static final int CONTINUE_USER_SWITCH_MSG = 35;
1542    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1543    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1544    static final int PERSIST_URI_GRANTS_MSG = 38;
1545    static final int REQUEST_ALL_PSS_MSG = 39;
1546    static final int START_PROFILES_MSG = 40;
1547    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1548    static final int SYSTEM_USER_START_MSG = 42;
1549    static final int SYSTEM_USER_CURRENT_MSG = 43;
1550    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1551    static final int FINISH_BOOTING_MSG = 45;
1552    static final int START_USER_SWITCH_UI_MSG = 46;
1553    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1554    static final int DISMISS_DIALOG_UI_MSG = 48;
1555    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1556    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1557    static final int DELETE_DUMPHEAP_MSG = 51;
1558    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1559    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1560    static final int REPORT_TIME_TRACKER_MSG = 54;
1561    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1562    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1563    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1564    static final int IDLE_UIDS_MSG = 58;
1565    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1566    static final int LOG_STACK_STATE = 60;
1567    static final int VR_MODE_CHANGE_MSG = 61;
1568    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1569    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1570    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1571    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1572    static final int START_USER_SWITCH_FG_MSG = 712;
1573
1574    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1575    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1576    static final int FIRST_COMPAT_MODE_MSG = 300;
1577    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1578
1579    static ServiceThread sKillThread = null;
1580    static KillHandler sKillHandler = null;
1581
1582    CompatModeDialog mCompatModeDialog;
1583    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1584    long mLastMemUsageReportTime = 0;
1585
1586    /**
1587     * Flag whether the current user is a "monkey", i.e. whether
1588     * the UI is driven by a UI automation tool.
1589     */
1590    private boolean mUserIsMonkey;
1591
1592    /** Flag whether the device has a Recents UI */
1593    boolean mHasRecents;
1594
1595    /** The dimensions of the thumbnails in the Recents UI. */
1596    int mThumbnailWidth;
1597    int mThumbnailHeight;
1598    float mFullscreenThumbnailScale;
1599
1600    /** The aspect ratio bounds of the PIP. */
1601    float mMinPipAspectRatio;
1602    float mMaxPipAspectRatio;
1603
1604    final ServiceThread mHandlerThread;
1605    final MainHandler mHandler;
1606    final UiHandler mUiHandler;
1607
1608    PackageManagerInternal mPackageManagerInt;
1609
1610    // VoiceInteraction session ID that changes for each new request except when
1611    // being called for multiwindow assist in a single session.
1612    private int mViSessionId = 1000;
1613
1614    final boolean mPermissionReviewRequired;
1615
1616    /**
1617     * Current global configuration information. Contains general settings for the entire system,
1618     * also corresponds to the merged configuration of the default display.
1619     */
1620    Configuration getGlobalConfiguration() {
1621        return mStackSupervisor.getConfiguration();
1622    }
1623
1624    final class KillHandler extends Handler {
1625        static final int KILL_PROCESS_GROUP_MSG = 4000;
1626
1627        public KillHandler(Looper looper) {
1628            super(looper, null, true);
1629        }
1630
1631        @Override
1632        public void handleMessage(Message msg) {
1633            switch (msg.what) {
1634                case KILL_PROCESS_GROUP_MSG:
1635                {
1636                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1637                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1638                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1639                }
1640                break;
1641
1642                default:
1643                    super.handleMessage(msg);
1644            }
1645        }
1646    }
1647
1648    final class UiHandler extends Handler {
1649        public UiHandler() {
1650            super(com.android.server.UiThread.get().getLooper(), null, true);
1651        }
1652
1653        @Override
1654        public void handleMessage(Message msg) {
1655            switch (msg.what) {
1656            case SHOW_ERROR_UI_MSG: {
1657                mAppErrors.handleShowAppErrorUi(msg);
1658                ensureBootCompleted();
1659            } break;
1660            case SHOW_NOT_RESPONDING_UI_MSG: {
1661                mAppErrors.handleShowAnrUi(msg);
1662                ensureBootCompleted();
1663            } break;
1664            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1665                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1666                synchronized (ActivityManagerService.this) {
1667                    ProcessRecord proc = (ProcessRecord) data.get("app");
1668                    if (proc == null) {
1669                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1670                        break;
1671                    }
1672                    if (proc.crashDialog != null) {
1673                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1674                        return;
1675                    }
1676                    AppErrorResult res = (AppErrorResult) data.get("result");
1677                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1678                        Dialog d = new StrictModeViolationDialog(mContext,
1679                                ActivityManagerService.this, res, proc);
1680                        d.show();
1681                        proc.crashDialog = d;
1682                    } else {
1683                        // The device is asleep, so just pretend that the user
1684                        // saw a crash dialog and hit "force quit".
1685                        res.set(0);
1686                    }
1687                }
1688                ensureBootCompleted();
1689            } break;
1690            case SHOW_FACTORY_ERROR_UI_MSG: {
1691                Dialog d = new FactoryErrorDialog(
1692                    mContext, msg.getData().getCharSequence("msg"));
1693                d.show();
1694                ensureBootCompleted();
1695            } break;
1696            case WAIT_FOR_DEBUGGER_UI_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    ProcessRecord app = (ProcessRecord)msg.obj;
1699                    if (msg.arg1 != 0) {
1700                        if (!app.waitedForDebugger) {
1701                            Dialog d = new AppWaitingForDebuggerDialog(
1702                                    ActivityManagerService.this,
1703                                    mContext, app);
1704                            app.waitDialog = d;
1705                            app.waitedForDebugger = true;
1706                            d.show();
1707                        }
1708                    } else {
1709                        if (app.waitDialog != null) {
1710                            app.waitDialog.dismiss();
1711                            app.waitDialog = null;
1712                        }
1713                    }
1714                }
1715            } break;
1716            case SHOW_UID_ERROR_UI_MSG: {
1717                if (mShowDialogs) {
1718                    AlertDialog d = new BaseErrorDialog(mContext);
1719                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1720                    d.setCancelable(false);
1721                    d.setTitle(mContext.getText(R.string.android_system_label));
1722                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1723                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1724                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1725                    d.show();
1726                }
1727            } break;
1728            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1729                if (mShowDialogs) {
1730                    AlertDialog d = new BaseErrorDialog(mContext);
1731                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1732                    d.setCancelable(false);
1733                    d.setTitle(mContext.getText(R.string.android_system_label));
1734                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1735                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1736                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1737                    d.show();
1738                }
1739            } break;
1740            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1741                synchronized (ActivityManagerService.this) {
1742                    ActivityRecord ar = (ActivityRecord) msg.obj;
1743                    if (mCompatModeDialog != null) {
1744                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1745                                ar.info.applicationInfo.packageName)) {
1746                            return;
1747                        }
1748                        mCompatModeDialog.dismiss();
1749                        mCompatModeDialog = null;
1750                    }
1751                    if (ar != null && false) {
1752                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1753                                ar.packageName)) {
1754                            int mode = mCompatModePackages.computeCompatModeLocked(
1755                                    ar.info.applicationInfo);
1756                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1757                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1758                                mCompatModeDialog = new CompatModeDialog(
1759                                        ActivityManagerService.this, mContext,
1760                                        ar.info.applicationInfo);
1761                                mCompatModeDialog.show();
1762                            }
1763                        }
1764                    }
1765                }
1766                break;
1767            }
1768            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1769                synchronized (ActivityManagerService.this) {
1770                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1771                    if (mUnsupportedDisplaySizeDialog != null) {
1772                        mUnsupportedDisplaySizeDialog.dismiss();
1773                        mUnsupportedDisplaySizeDialog = null;
1774                    }
1775                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1776                            ar.packageName)) {
1777                        // TODO(multi-display): Show dialog on appropriate display.
1778                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1779                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1780                        mUnsupportedDisplaySizeDialog.show();
1781                    }
1782                }
1783                break;
1784            }
1785            case START_USER_SWITCH_UI_MSG: {
1786                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1787                break;
1788            }
1789            case DISMISS_DIALOG_UI_MSG: {
1790                final Dialog d = (Dialog) msg.obj;
1791                d.dismiss();
1792                break;
1793            }
1794            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1795                dispatchProcessesChanged();
1796                break;
1797            }
1798            case DISPATCH_PROCESS_DIED_UI_MSG: {
1799                final int pid = msg.arg1;
1800                final int uid = msg.arg2;
1801                dispatchProcessDied(pid, uid);
1802                break;
1803            }
1804            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1805                dispatchUidsChanged();
1806            } break;
1807            }
1808        }
1809    }
1810
1811    final class MainHandler extends Handler {
1812        public MainHandler(Looper looper) {
1813            super(looper, null, true);
1814        }
1815
1816        @Override
1817        public void handleMessage(Message msg) {
1818            switch (msg.what) {
1819            case UPDATE_CONFIGURATION_MSG: {
1820                final ContentResolver resolver = mContext.getContentResolver();
1821                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1822                        msg.arg1);
1823            } break;
1824            case GC_BACKGROUND_PROCESSES_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    performAppGcsIfAppropriateLocked();
1827                }
1828            } break;
1829            case SERVICE_TIMEOUT_MSG: {
1830                if (mDidDexOpt) {
1831                    mDidDexOpt = false;
1832                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1833                    nmsg.obj = msg.obj;
1834                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1835                    return;
1836                }
1837                mServices.serviceTimeout((ProcessRecord)msg.obj);
1838            } break;
1839            case UPDATE_TIME_ZONE: {
1840                synchronized (ActivityManagerService.this) {
1841                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1842                        ProcessRecord r = mLruProcesses.get(i);
1843                        if (r.thread != null) {
1844                            try {
1845                                r.thread.updateTimeZone();
1846                            } catch (RemoteException ex) {
1847                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1848                            }
1849                        }
1850                    }
1851                }
1852            } break;
1853            case CLEAR_DNS_CACHE_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1856                        ProcessRecord r = mLruProcesses.get(i);
1857                        if (r.thread != null) {
1858                            try {
1859                                r.thread.clearDnsCache();
1860                            } catch (RemoteException ex) {
1861                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1862                            }
1863                        }
1864                    }
1865                }
1866            } break;
1867            case UPDATE_HTTP_PROXY_MSG: {
1868                ProxyInfo proxy = (ProxyInfo)msg.obj;
1869                String host = "";
1870                String port = "";
1871                String exclList = "";
1872                Uri pacFileUrl = Uri.EMPTY;
1873                if (proxy != null) {
1874                    host = proxy.getHost();
1875                    port = Integer.toString(proxy.getPort());
1876                    exclList = proxy.getExclusionListAsString();
1877                    pacFileUrl = proxy.getPacFileUrl();
1878                }
1879                synchronized (ActivityManagerService.this) {
1880                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1881                        ProcessRecord r = mLruProcesses.get(i);
1882                        if (r.thread != null) {
1883                            try {
1884                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1885                            } catch (RemoteException ex) {
1886                                Slog.w(TAG, "Failed to update http proxy for: " +
1887                                        r.info.processName);
1888                            }
1889                        }
1890                    }
1891                }
1892            } break;
1893            case PROC_START_TIMEOUT_MSG: {
1894                if (mDidDexOpt) {
1895                    mDidDexOpt = false;
1896                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1897                    nmsg.obj = msg.obj;
1898                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1899                    return;
1900                }
1901                ProcessRecord app = (ProcessRecord)msg.obj;
1902                synchronized (ActivityManagerService.this) {
1903                    processStartTimedOutLocked(app);
1904                }
1905            } break;
1906            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1907                ProcessRecord app = (ProcessRecord)msg.obj;
1908                synchronized (ActivityManagerService.this) {
1909                    processContentProviderPublishTimedOutLocked(app);
1910                }
1911            } break;
1912            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1913                synchronized (ActivityManagerService.this) {
1914                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1915                }
1916            } break;
1917            case KILL_APPLICATION_MSG: {
1918                synchronized (ActivityManagerService.this) {
1919                    final int appId = msg.arg1;
1920                    final int userId = msg.arg2;
1921                    Bundle bundle = (Bundle)msg.obj;
1922                    String pkg = bundle.getString("pkg");
1923                    String reason = bundle.getString("reason");
1924                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1925                            false, userId, reason);
1926                }
1927            } break;
1928            case FINALIZE_PENDING_INTENT_MSG: {
1929                ((PendingIntentRecord)msg.obj).completeFinalize();
1930            } break;
1931            case POST_HEAVY_NOTIFICATION_MSG: {
1932                INotificationManager inm = NotificationManager.getService();
1933                if (inm == null) {
1934                    return;
1935                }
1936
1937                ActivityRecord root = (ActivityRecord)msg.obj;
1938                ProcessRecord process = root.app;
1939                if (process == null) {
1940                    return;
1941                }
1942
1943                try {
1944                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1945                    String text = mContext.getString(R.string.heavy_weight_notification,
1946                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1947                    Notification notification = new Notification.Builder(context)
1948                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1949                            .setWhen(0)
1950                            .setOngoing(true)
1951                            .setTicker(text)
1952                            .setColor(mContext.getColor(
1953                                    com.android.internal.R.color.system_notification_accent_color))
1954                            .setContentTitle(text)
1955                            .setContentText(
1956                                    mContext.getText(R.string.heavy_weight_notification_detail))
1957                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1958                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1959                                    new UserHandle(root.userId)))
1960                            .build();
1961                    try {
1962                        int[] outId = new int[1];
1963                        inm.enqueueNotificationWithTag("android", "android", null,
1964                                R.string.heavy_weight_notification,
1965                                notification, outId, root.userId);
1966                    } catch (RuntimeException e) {
1967                        Slog.w(ActivityManagerService.TAG,
1968                                "Error showing notification for heavy-weight app", e);
1969                    } catch (RemoteException e) {
1970                    }
1971                } catch (NameNotFoundException e) {
1972                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1973                }
1974            } break;
1975            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1976                INotificationManager inm = NotificationManager.getService();
1977                if (inm == null) {
1978                    return;
1979                }
1980                try {
1981                    inm.cancelNotificationWithTag("android", null,
1982                            R.string.heavy_weight_notification,  msg.arg1);
1983                } catch (RuntimeException e) {
1984                    Slog.w(ActivityManagerService.TAG,
1985                            "Error canceling notification for service", e);
1986                } catch (RemoteException e) {
1987                }
1988            } break;
1989            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1990                synchronized (ActivityManagerService.this) {
1991                    checkExcessivePowerUsageLocked(true);
1992                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1993                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1994                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1995                }
1996            } break;
1997            case REPORT_MEM_USAGE_MSG: {
1998                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1999                Thread thread = new Thread() {
2000                    @Override public void run() {
2001                        reportMemUsage(memInfos);
2002                    }
2003                };
2004                thread.start();
2005                break;
2006            }
2007            case START_USER_SWITCH_FG_MSG: {
2008                mUserController.startUserInForeground(msg.arg1);
2009                break;
2010            }
2011            case REPORT_USER_SWITCH_MSG: {
2012                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2013                break;
2014            }
2015            case CONTINUE_USER_SWITCH_MSG: {
2016                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2017                break;
2018            }
2019            case USER_SWITCH_TIMEOUT_MSG: {
2020                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2021                break;
2022            }
2023            case IMMERSIVE_MODE_LOCK_MSG: {
2024                final boolean nextState = (msg.arg1 != 0);
2025                if (mUpdateLock.isHeld() != nextState) {
2026                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2027                            "Applying new update lock state '" + nextState
2028                            + "' for " + (ActivityRecord)msg.obj);
2029                    if (nextState) {
2030                        mUpdateLock.acquire();
2031                    } else {
2032                        mUpdateLock.release();
2033                    }
2034                }
2035                break;
2036            }
2037            case PERSIST_URI_GRANTS_MSG: {
2038                writeGrantedUriPermissions();
2039                break;
2040            }
2041            case REQUEST_ALL_PSS_MSG: {
2042                synchronized (ActivityManagerService.this) {
2043                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2044                }
2045                break;
2046            }
2047            case START_PROFILES_MSG: {
2048                synchronized (ActivityManagerService.this) {
2049                    mUserController.startProfilesLocked();
2050                }
2051                break;
2052            }
2053            case UPDATE_TIME_PREFERENCE_MSG: {
2054                // The user's time format preference might have changed.
2055                // For convenience we re-use the Intent extra values.
2056                synchronized (ActivityManagerService.this) {
2057                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2058                        ProcessRecord r = mLruProcesses.get(i);
2059                        if (r.thread != null) {
2060                            try {
2061                                r.thread.updateTimePrefs(msg.arg1);
2062                            } catch (RemoteException ex) {
2063                                Slog.w(TAG, "Failed to update preferences for: "
2064                                        + r.info.processName);
2065                            }
2066                        }
2067                    }
2068                }
2069                break;
2070            }
2071            case SYSTEM_USER_START_MSG: {
2072                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2073                        Integer.toString(msg.arg1), msg.arg1);
2074                mSystemServiceManager.startUser(msg.arg1);
2075                break;
2076            }
2077            case SYSTEM_USER_UNLOCK_MSG: {
2078                final int userId = msg.arg1;
2079                mSystemServiceManager.unlockUser(userId);
2080                synchronized (ActivityManagerService.this) {
2081                    mRecentTasks.loadUserRecentsLocked(userId);
2082                }
2083                if (userId == UserHandle.USER_SYSTEM) {
2084                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2085                }
2086                installEncryptionUnawareProviders(userId);
2087                mUserController.finishUserUnlocked((UserState) msg.obj);
2088                break;
2089            }
2090            case SYSTEM_USER_CURRENT_MSG: {
2091                mBatteryStatsService.noteEvent(
2092                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2093                        Integer.toString(msg.arg2), msg.arg2);
2094                mBatteryStatsService.noteEvent(
2095                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2096                        Integer.toString(msg.arg1), msg.arg1);
2097                mSystemServiceManager.switchUser(msg.arg1);
2098                break;
2099            }
2100            case ENTER_ANIMATION_COMPLETE_MSG: {
2101                synchronized (ActivityManagerService.this) {
2102                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2103                    if (r != null && r.app != null && r.app.thread != null) {
2104                        try {
2105                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2106                        } catch (RemoteException e) {
2107                        }
2108                    }
2109                }
2110                break;
2111            }
2112            case FINISH_BOOTING_MSG: {
2113                if (msg.arg1 != 0) {
2114                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2115                    finishBooting();
2116                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2117                }
2118                if (msg.arg2 != 0) {
2119                    enableScreenAfterBoot();
2120                }
2121                break;
2122            }
2123            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2124                try {
2125                    Locale l = (Locale) msg.obj;
2126                    IBinder service = ServiceManager.getService("mount");
2127                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2128                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2129                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2130                } catch (RemoteException e) {
2131                    Log.e(TAG, "Error storing locale for decryption UI", e);
2132                }
2133                break;
2134            }
2135            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2136                final int uid = msg.arg1;
2137                final byte[] firstPacket = (byte[]) msg.obj;
2138
2139                synchronized (mPidsSelfLocked) {
2140                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2141                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2142                        if (p.uid == uid) {
2143                            try {
2144                                p.thread.notifyCleartextNetwork(firstPacket);
2145                            } catch (RemoteException ignored) {
2146                            }
2147                        }
2148                    }
2149                }
2150                break;
2151            }
2152            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2153                final String procName;
2154                final int uid;
2155                final long memLimit;
2156                final String reportPackage;
2157                synchronized (ActivityManagerService.this) {
2158                    procName = mMemWatchDumpProcName;
2159                    uid = mMemWatchDumpUid;
2160                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2161                    if (val == null) {
2162                        val = mMemWatchProcesses.get(procName, 0);
2163                    }
2164                    if (val != null) {
2165                        memLimit = val.first;
2166                        reportPackage = val.second;
2167                    } else {
2168                        memLimit = 0;
2169                        reportPackage = null;
2170                    }
2171                }
2172                if (procName == null) {
2173                    return;
2174                }
2175
2176                if (DEBUG_PSS) Slog.d(TAG_PSS,
2177                        "Showing dump heap notification from " + procName + "/" + uid);
2178
2179                INotificationManager inm = NotificationManager.getService();
2180                if (inm == null) {
2181                    return;
2182                }
2183
2184                String text = mContext.getString(R.string.dump_heap_notification, procName);
2185
2186
2187                Intent deleteIntent = new Intent();
2188                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2189                Intent intent = new Intent();
2190                intent.setClassName("android", DumpHeapActivity.class.getName());
2191                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2192                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2193                if (reportPackage != null) {
2194                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2195                }
2196                int userId = UserHandle.getUserId(uid);
2197                Notification notification = new Notification.Builder(mContext)
2198                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2199                        .setWhen(0)
2200                        .setOngoing(true)
2201                        .setAutoCancel(true)
2202                        .setTicker(text)
2203                        .setColor(mContext.getColor(
2204                                com.android.internal.R.color.system_notification_accent_color))
2205                        .setContentTitle(text)
2206                        .setContentText(
2207                                mContext.getText(R.string.dump_heap_notification_detail))
2208                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2209                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2210                                new UserHandle(userId)))
2211                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2212                                deleteIntent, 0, UserHandle.SYSTEM))
2213                        .build();
2214
2215                try {
2216                    int[] outId = new int[1];
2217                    inm.enqueueNotificationWithTag("android", "android", null,
2218                            R.string.dump_heap_notification,
2219                            notification, outId, userId);
2220                } catch (RuntimeException e) {
2221                    Slog.w(ActivityManagerService.TAG,
2222                            "Error showing notification for dump heap", e);
2223                } catch (RemoteException e) {
2224                }
2225            } break;
2226            case DELETE_DUMPHEAP_MSG: {
2227                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2228                        DumpHeapActivity.JAVA_URI,
2229                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2230                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2231                        UserHandle.myUserId());
2232                synchronized (ActivityManagerService.this) {
2233                    mMemWatchDumpFile = null;
2234                    mMemWatchDumpProcName = null;
2235                    mMemWatchDumpPid = -1;
2236                    mMemWatchDumpUid = -1;
2237                }
2238            } break;
2239            case FOREGROUND_PROFILE_CHANGED_MSG: {
2240                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2241            } break;
2242            case REPORT_TIME_TRACKER_MSG: {
2243                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2244                tracker.deliverResult(mContext);
2245            } break;
2246            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2247                mUserController.dispatchUserSwitchComplete(msg.arg1);
2248            } break;
2249            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2250                mUserController.dispatchLockedBootComplete(msg.arg1);
2251            } break;
2252            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2253                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2254                try {
2255                    connection.shutdown();
2256                } catch (RemoteException e) {
2257                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2258                }
2259                // Only a UiAutomation can set this flag and now that
2260                // it is finished we make sure it is reset to its default.
2261                mUserIsMonkey = false;
2262            } break;
2263            case IDLE_UIDS_MSG: {
2264                idleUids();
2265            } break;
2266            case VR_MODE_CHANGE_MSG: {
2267                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2268                if (vrService == null) {
2269                    break;
2270                }
2271                final ActivityRecord r = (ActivityRecord) msg.obj;
2272                boolean vrMode;
2273                ComponentName requestedPackage;
2274                ComponentName callingPackage;
2275                int userId;
2276                synchronized (ActivityManagerService.this) {
2277                    vrMode = r.requestedVrComponent != null;
2278                    requestedPackage = r.requestedVrComponent;
2279                    userId = r.userId;
2280                    callingPackage = r.info.getComponentName();
2281                    if (mInVrMode != vrMode) {
2282                        mInVrMode = vrMode;
2283                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2284                        if (r.app != null) {
2285                            ProcessRecord proc = r.app;
2286                            if (proc.vrThreadTid > 0) {
2287                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2288                                    try {
2289                                        if (mInVrMode == true) {
2290                                            Process.setThreadScheduler(proc.vrThreadTid,
2291                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2292                                        } else {
2293                                            Process.setThreadScheduler(proc.vrThreadTid,
2294                                                Process.SCHED_OTHER, 0);
2295                                        }
2296                                    } catch (IllegalArgumentException e) {
2297                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2298                                                + " not exist:\n" + e);
2299                                    }
2300                                }
2301                            }
2302                        }
2303                    }
2304                }
2305                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2306            } case NOTIFY_VR_SLEEPING_MSG: {
2307                notifyVrManagerOfSleepState(msg.arg1 != 0);
2308            } break;
2309            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2310                synchronized (ActivityManagerService.this) {
2311                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2312                        ProcessRecord r = mLruProcesses.get(i);
2313                        if (r.thread != null) {
2314                            try {
2315                                r.thread.handleTrustStorageUpdate();
2316                            } catch (RemoteException ex) {
2317                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2318                                        r.info.processName);
2319                            }
2320                        }
2321                    }
2322                }
2323            } break;
2324            }
2325        }
2326    };
2327
2328    static final int COLLECT_PSS_BG_MSG = 1;
2329
2330    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2331        @Override
2332        public void handleMessage(Message msg) {
2333            switch (msg.what) {
2334            case COLLECT_PSS_BG_MSG: {
2335                long start = SystemClock.uptimeMillis();
2336                MemInfoReader memInfo = null;
2337                synchronized (ActivityManagerService.this) {
2338                    if (mFullPssPending) {
2339                        mFullPssPending = false;
2340                        memInfo = new MemInfoReader();
2341                    }
2342                }
2343                if (memInfo != null) {
2344                    updateCpuStatsNow();
2345                    long nativeTotalPss = 0;
2346                    final List<ProcessCpuTracker.Stats> stats;
2347                    synchronized (mProcessCpuTracker) {
2348                        stats = mProcessCpuTracker.getStats( (st)-> {
2349                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2350                        });
2351                    }
2352                    final int N = stats.size();
2353                    for (int j = 0; j < N; j++) {
2354                        synchronized (mPidsSelfLocked) {
2355                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2356                                // This is one of our own processes; skip it.
2357                                continue;
2358                            }
2359                        }
2360                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2361                    }
2362                    memInfo.readMemInfo();
2363                    synchronized (ActivityManagerService.this) {
2364                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2365                                + (SystemClock.uptimeMillis()-start) + "ms");
2366                        final long cachedKb = memInfo.getCachedSizeKb();
2367                        final long freeKb = memInfo.getFreeSizeKb();
2368                        final long zramKb = memInfo.getZramTotalSizeKb();
2369                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2370                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2371                                kernelKb*1024, nativeTotalPss*1024);
2372                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2373                                nativeTotalPss);
2374                    }
2375                }
2376
2377                int num = 0;
2378                long[] tmp = new long[2];
2379                do {
2380                    ProcessRecord proc;
2381                    int procState;
2382                    int pid;
2383                    long lastPssTime;
2384                    synchronized (ActivityManagerService.this) {
2385                        if (mPendingPssProcesses.size() <= 0) {
2386                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2387                                    "Collected PSS of " + num + " processes in "
2388                                    + (SystemClock.uptimeMillis() - start) + "ms");
2389                            mPendingPssProcesses.clear();
2390                            return;
2391                        }
2392                        proc = mPendingPssProcesses.remove(0);
2393                        procState = proc.pssProcState;
2394                        lastPssTime = proc.lastPssTime;
2395                        if (proc.thread != null && procState == proc.setProcState
2396                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2397                                        < SystemClock.uptimeMillis()) {
2398                            pid = proc.pid;
2399                        } else {
2400                            proc = null;
2401                            pid = 0;
2402                        }
2403                    }
2404                    if (proc != null) {
2405                        long pss = Debug.getPss(pid, tmp, null);
2406                        synchronized (ActivityManagerService.this) {
2407                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2408                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2409                                num++;
2410                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2411                                        SystemClock.uptimeMillis());
2412                            }
2413                        }
2414                    }
2415                } while (true);
2416            }
2417            }
2418        }
2419    };
2420
2421    public void setSystemProcess() {
2422        try {
2423            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2424            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2425            ServiceManager.addService("meminfo", new MemBinder(this));
2426            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2427            ServiceManager.addService("dbinfo", new DbBinder(this));
2428            if (MONITOR_CPU_USAGE) {
2429                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2430            }
2431            ServiceManager.addService("permission", new PermissionController(this));
2432            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2433
2434            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2435                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2436            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2437
2438            synchronized (this) {
2439                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2440                app.persistent = true;
2441                app.pid = MY_PID;
2442                app.maxAdj = ProcessList.SYSTEM_ADJ;
2443                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2444                synchronized (mPidsSelfLocked) {
2445                    mPidsSelfLocked.put(app.pid, app);
2446                }
2447                updateLruProcessLocked(app, false, null);
2448                updateOomAdjLocked();
2449            }
2450        } catch (PackageManager.NameNotFoundException e) {
2451            throw new RuntimeException(
2452                    "Unable to find android system package", e);
2453        }
2454    }
2455
2456    public void setWindowManager(WindowManagerService wm) {
2457        mWindowManager = wm;
2458        mStackSupervisor.setWindowManager(wm);
2459        mActivityStarter.setWindowManager(wm);
2460    }
2461
2462    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2463        mUsageStatsService = usageStatsManager;
2464    }
2465
2466    public void startObservingNativeCrashes() {
2467        final NativeCrashListener ncl = new NativeCrashListener(this);
2468        ncl.start();
2469    }
2470
2471    public IAppOpsService getAppOpsService() {
2472        return mAppOpsService;
2473    }
2474
2475    static class MemBinder extends Binder {
2476        ActivityManagerService mActivityManagerService;
2477        MemBinder(ActivityManagerService activityManagerService) {
2478            mActivityManagerService = activityManagerService;
2479        }
2480
2481        @Override
2482        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2483            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2484                    != PackageManager.PERMISSION_GRANTED) {
2485                pw.println("Permission Denial: can't dump meminfo from from pid="
2486                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2487                        + " without permission " + android.Manifest.permission.DUMP);
2488                return;
2489            }
2490
2491            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2492        }
2493    }
2494
2495    static class GraphicsBinder extends Binder {
2496        ActivityManagerService mActivityManagerService;
2497        GraphicsBinder(ActivityManagerService activityManagerService) {
2498            mActivityManagerService = activityManagerService;
2499        }
2500
2501        @Override
2502        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2503            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2504                    != PackageManager.PERMISSION_GRANTED) {
2505                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2506                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2507                        + " without permission " + android.Manifest.permission.DUMP);
2508                return;
2509            }
2510
2511            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2512        }
2513    }
2514
2515    static class DbBinder extends Binder {
2516        ActivityManagerService mActivityManagerService;
2517        DbBinder(ActivityManagerService activityManagerService) {
2518            mActivityManagerService = activityManagerService;
2519        }
2520
2521        @Override
2522        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2523            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2524                    != PackageManager.PERMISSION_GRANTED) {
2525                pw.println("Permission Denial: can't dump dbinfo from from pid="
2526                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2527                        + " without permission " + android.Manifest.permission.DUMP);
2528                return;
2529            }
2530
2531            mActivityManagerService.dumpDbInfo(fd, pw, args);
2532        }
2533    }
2534
2535    static class CpuBinder extends Binder {
2536        ActivityManagerService mActivityManagerService;
2537        CpuBinder(ActivityManagerService activityManagerService) {
2538            mActivityManagerService = activityManagerService;
2539        }
2540
2541        @Override
2542        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2543            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2544                    != PackageManager.PERMISSION_GRANTED) {
2545                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2546                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2547                        + " without permission " + android.Manifest.permission.DUMP);
2548                return;
2549            }
2550
2551            synchronized (mActivityManagerService.mProcessCpuTracker) {
2552                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2553                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2554                        SystemClock.uptimeMillis()));
2555            }
2556        }
2557    }
2558
2559    public static final class Lifecycle extends SystemService {
2560        private final ActivityManagerService mService;
2561
2562        public Lifecycle(Context context) {
2563            super(context);
2564            mService = new ActivityManagerService(context);
2565        }
2566
2567        @Override
2568        public void onStart() {
2569            mService.start();
2570        }
2571
2572        public ActivityManagerService getService() {
2573            return mService;
2574        }
2575    }
2576
2577    // Note: This method is invoked on the main thread but may need to attach various
2578    // handlers to other threads.  So take care to be explicit about the looper.
2579    public ActivityManagerService(Context systemContext) {
2580        mContext = systemContext;
2581        mFactoryTest = FactoryTest.getMode();
2582        mSystemThread = ActivityThread.currentActivityThread();
2583
2584        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2585
2586        mPermissionReviewRequired = mContext.getResources().getBoolean(
2587                com.android.internal.R.bool.config_permissionReviewRequired);
2588
2589        mHandlerThread = new ServiceThread(TAG,
2590                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2591        mHandlerThread.start();
2592        mHandler = new MainHandler(mHandlerThread.getLooper());
2593        mUiHandler = new UiHandler();
2594
2595        /* static; one-time init here */
2596        if (sKillHandler == null) {
2597            sKillThread = new ServiceThread(TAG + ":kill",
2598                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2599            sKillThread.start();
2600            sKillHandler = new KillHandler(sKillThread.getLooper());
2601        }
2602
2603        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2604                "foreground", BROADCAST_FG_TIMEOUT, false);
2605        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2606                "background", BROADCAST_BG_TIMEOUT, true);
2607        mBroadcastQueues[0] = mFgBroadcastQueue;
2608        mBroadcastQueues[1] = mBgBroadcastQueue;
2609
2610        mServices = new ActiveServices(this);
2611        mProviderMap = new ProviderMap(this);
2612        mAppErrors = new AppErrors(mContext, this);
2613
2614        // TODO: Move creation of battery stats service outside of activity manager service.
2615        File dataDir = Environment.getDataDirectory();
2616        File systemDir = new File(dataDir, "system");
2617        systemDir.mkdirs();
2618        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2619        mBatteryStatsService.getActiveStatistics().readLocked();
2620        mBatteryStatsService.scheduleWriteToDisk();
2621        mOnBattery = DEBUG_POWER ? true
2622                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2623        mBatteryStatsService.getActiveStatistics().setCallback(this);
2624
2625        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2626
2627        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2628        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2629                new IAppOpsCallback.Stub() {
2630                    @Override public void opChanged(int op, int uid, String packageName) {
2631                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2632                            if (mAppOpsService.checkOperation(op, uid, packageName)
2633                                    != AppOpsManager.MODE_ALLOWED) {
2634                                runInBackgroundDisabled(uid);
2635                            }
2636                        }
2637                    }
2638                });
2639
2640        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2641
2642        mUserController = new UserController(this);
2643
2644        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2645            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2646
2647        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2648            mUseFifoUiScheduling = true;
2649        }
2650
2651        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2652        mTempConfig.setToDefaults();
2653        mTempConfig.setLocales(LocaleList.getDefault());
2654        mConfigurationSeq = mTempConfig.seq = 1;
2655        mStackSupervisor = new ActivityStackSupervisor(this);
2656        mStackSupervisor.onConfigurationChanged(mTempConfig);
2657        mKeyguardController = mStackSupervisor.mKeyguardController;
2658        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2659        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2660        mTaskChangeNotificationController =
2661                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2662        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2663        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2664
2665        mProcessCpuThread = new Thread("CpuTracker") {
2666            @Override
2667            public void run() {
2668                synchronized (mProcessCpuTracker) {
2669                    mProcessCpuInitLatch.countDown();
2670                    mProcessCpuTracker.init();
2671                }
2672                while (true) {
2673                    try {
2674                        try {
2675                            synchronized(this) {
2676                                final long now = SystemClock.uptimeMillis();
2677                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2678                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2679                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2680                                //        + ", write delay=" + nextWriteDelay);
2681                                if (nextWriteDelay < nextCpuDelay) {
2682                                    nextCpuDelay = nextWriteDelay;
2683                                }
2684                                if (nextCpuDelay > 0) {
2685                                    mProcessCpuMutexFree.set(true);
2686                                    this.wait(nextCpuDelay);
2687                                }
2688                            }
2689                        } catch (InterruptedException e) {
2690                        }
2691                        updateCpuStatsNow();
2692                    } catch (Exception e) {
2693                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2694                    }
2695                }
2696            }
2697        };
2698
2699        Watchdog.getInstance().addMonitor(this);
2700        Watchdog.getInstance().addThread(mHandler);
2701    }
2702
2703    public void setSystemServiceManager(SystemServiceManager mgr) {
2704        mSystemServiceManager = mgr;
2705    }
2706
2707    public void setInstaller(Installer installer) {
2708        mInstaller = installer;
2709    }
2710
2711    private void start() {
2712        Process.removeAllProcessGroups();
2713        mProcessCpuThread.start();
2714
2715        mBatteryStatsService.publish(mContext);
2716        mAppOpsService.publish(mContext);
2717        Slog.d("AppOps", "AppOpsService published");
2718        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2719        // Wait for the synchronized block started in mProcessCpuThread,
2720        // so that any other acccess to mProcessCpuTracker from main thread
2721        // will be blocked during mProcessCpuTracker initialization.
2722        try {
2723            mProcessCpuInitLatch.await();
2724        } catch (InterruptedException e) {
2725            Slog.wtf(TAG, "Interrupted wait during start", e);
2726            Thread.currentThread().interrupt();
2727            throw new IllegalStateException("Interrupted wait during start");
2728        }
2729    }
2730
2731    void onUserStoppedLocked(int userId) {
2732        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2733    }
2734
2735    public void initPowerManagement() {
2736        mStackSupervisor.initPowerManagement();
2737        mBatteryStatsService.initPowerManagement();
2738        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2739        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2740        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2741        mVoiceWakeLock.setReferenceCounted(false);
2742    }
2743
2744    @Override
2745    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2746            throws RemoteException {
2747        if (code == SYSPROPS_TRANSACTION) {
2748            // We need to tell all apps about the system property change.
2749            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2750            synchronized(this) {
2751                final int NP = mProcessNames.getMap().size();
2752                for (int ip=0; ip<NP; ip++) {
2753                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2754                    final int NA = apps.size();
2755                    for (int ia=0; ia<NA; ia++) {
2756                        ProcessRecord app = apps.valueAt(ia);
2757                        if (app.thread != null) {
2758                            procs.add(app.thread.asBinder());
2759                        }
2760                    }
2761                }
2762            }
2763
2764            int N = procs.size();
2765            for (int i=0; i<N; i++) {
2766                Parcel data2 = Parcel.obtain();
2767                try {
2768                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2769                            Binder.FLAG_ONEWAY);
2770                } catch (RemoteException e) {
2771                }
2772                data2.recycle();
2773            }
2774        }
2775        try {
2776            return super.onTransact(code, data, reply, flags);
2777        } catch (RuntimeException e) {
2778            // The activity manager only throws security exceptions, so let's
2779            // log all others.
2780            if (!(e instanceof SecurityException)) {
2781                Slog.wtf(TAG, "Activity Manager Crash", e);
2782            }
2783            throw e;
2784        }
2785    }
2786
2787    void updateCpuStats() {
2788        final long now = SystemClock.uptimeMillis();
2789        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2790            return;
2791        }
2792        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2793            synchronized (mProcessCpuThread) {
2794                mProcessCpuThread.notify();
2795            }
2796        }
2797    }
2798
2799    void updateCpuStatsNow() {
2800        synchronized (mProcessCpuTracker) {
2801            mProcessCpuMutexFree.set(false);
2802            final long now = SystemClock.uptimeMillis();
2803            boolean haveNewCpuStats = false;
2804
2805            if (MONITOR_CPU_USAGE &&
2806                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2807                mLastCpuTime.set(now);
2808                mProcessCpuTracker.update();
2809                if (mProcessCpuTracker.hasGoodLastStats()) {
2810                    haveNewCpuStats = true;
2811                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2812                    //Slog.i(TAG, "Total CPU usage: "
2813                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2814
2815                    // Slog the cpu usage if the property is set.
2816                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2817                        int user = mProcessCpuTracker.getLastUserTime();
2818                        int system = mProcessCpuTracker.getLastSystemTime();
2819                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2820                        int irq = mProcessCpuTracker.getLastIrqTime();
2821                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2822                        int idle = mProcessCpuTracker.getLastIdleTime();
2823
2824                        int total = user + system + iowait + irq + softIrq + idle;
2825                        if (total == 0) total = 1;
2826
2827                        EventLog.writeEvent(EventLogTags.CPU,
2828                                ((user+system+iowait+irq+softIrq) * 100) / total,
2829                                (user * 100) / total,
2830                                (system * 100) / total,
2831                                (iowait * 100) / total,
2832                                (irq * 100) / total,
2833                                (softIrq * 100) / total);
2834                    }
2835                }
2836            }
2837
2838            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2839            synchronized(bstats) {
2840                synchronized(mPidsSelfLocked) {
2841                    if (haveNewCpuStats) {
2842                        if (bstats.startAddingCpuLocked()) {
2843                            int totalUTime = 0;
2844                            int totalSTime = 0;
2845                            final int N = mProcessCpuTracker.countStats();
2846                            for (int i=0; i<N; i++) {
2847                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2848                                if (!st.working) {
2849                                    continue;
2850                                }
2851                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2852                                totalUTime += st.rel_utime;
2853                                totalSTime += st.rel_stime;
2854                                if (pr != null) {
2855                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2856                                    if (ps == null || !ps.isActive()) {
2857                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2858                                                pr.info.uid, pr.processName);
2859                                    }
2860                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2861                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2862                                } else {
2863                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2864                                    if (ps == null || !ps.isActive()) {
2865                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2866                                                bstats.mapUid(st.uid), st.name);
2867                                    }
2868                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2869                                }
2870                            }
2871                            final int userTime = mProcessCpuTracker.getLastUserTime();
2872                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2873                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2874                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2875                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2876                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2877                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2878                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2879                        }
2880                    }
2881                }
2882
2883                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2884                    mLastWriteTime = now;
2885                    mBatteryStatsService.scheduleWriteToDisk();
2886                }
2887            }
2888        }
2889    }
2890
2891    @Override
2892    public void batteryNeedsCpuUpdate() {
2893        updateCpuStatsNow();
2894    }
2895
2896    @Override
2897    public void batteryPowerChanged(boolean onBattery) {
2898        // When plugging in, update the CPU stats first before changing
2899        // the plug state.
2900        updateCpuStatsNow();
2901        synchronized (this) {
2902            synchronized(mPidsSelfLocked) {
2903                mOnBattery = DEBUG_POWER ? true : onBattery;
2904            }
2905        }
2906    }
2907
2908    @Override
2909    public void batterySendBroadcast(Intent intent) {
2910        synchronized (this) {
2911            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2912                    AppOpsManager.OP_NONE, null, false, false,
2913                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2914        }
2915    }
2916
2917    /**
2918     * Initialize the application bind args. These are passed to each
2919     * process when the bindApplication() IPC is sent to the process. They're
2920     * lazily setup to make sure the services are running when they're asked for.
2921     */
2922    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2923        // Isolated processes won't get this optimization, so that we don't
2924        // violate the rules about which services they have access to.
2925        if (isolated) {
2926            if (mIsolatedAppBindArgs == null) {
2927                mIsolatedAppBindArgs = new HashMap<>();
2928                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2929            }
2930            return mIsolatedAppBindArgs;
2931        }
2932
2933        if (mAppBindArgs == null) {
2934            mAppBindArgs = new HashMap<>();
2935
2936            // Setup the application init args
2937            mAppBindArgs.put("package", ServiceManager.getService("package"));
2938            mAppBindArgs.put("window", ServiceManager.getService("window"));
2939            mAppBindArgs.put(Context.ALARM_SERVICE,
2940                    ServiceManager.getService(Context.ALARM_SERVICE));
2941        }
2942        return mAppBindArgs;
2943    }
2944
2945    /**
2946     * Update AMS states when an activity is resumed. This should only be called by
2947     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2948     */
2949    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2950        if (r.task.isApplicationTask()) {
2951            if (mCurAppTimeTracker != r.appTimeTracker) {
2952                // We are switching app tracking.  Complete the current one.
2953                if (mCurAppTimeTracker != null) {
2954                    mCurAppTimeTracker.stop();
2955                    mHandler.obtainMessage(
2956                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2957                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2958                    mCurAppTimeTracker = null;
2959                }
2960                if (r.appTimeTracker != null) {
2961                    mCurAppTimeTracker = r.appTimeTracker;
2962                    startTimeTrackingFocusedActivityLocked();
2963                }
2964            } else {
2965                startTimeTrackingFocusedActivityLocked();
2966            }
2967        } else {
2968            r.appTimeTracker = null;
2969        }
2970        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2971        // TODO: Probably not, because we don't want to resume voice on switching
2972        // back to this activity
2973        if (r.task.voiceInteractor != null) {
2974            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2975        } else {
2976            finishRunningVoiceLocked();
2977            IVoiceInteractionSession session;
2978            if (mLastResumedActivity != null
2979                    && ((session = mLastResumedActivity.task.voiceSession) != null
2980                    || (session = mLastResumedActivity.voiceSession) != null)) {
2981                // We had been in a voice interaction session, but now focused has
2982                // move to something different.  Just finish the session, we can't
2983                // return to it and retain the proper state and synchronization with
2984                // the voice interaction service.
2985                finishVoiceTask(session);
2986            }
2987        }
2988
2989        mWindowManager.setFocusedApp(r.appToken, true);
2990
2991        applyUpdateLockStateLocked(r);
2992        applyUpdateVrModeLocked(r);
2993        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2994            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2995            mHandler.obtainMessage(
2996                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
2997        }
2998
2999        mLastResumedActivity = r;
3000
3001        EventLogTags.writeAmSetResumedActivity(
3002                r == null ? -1 : r.userId,
3003                r == null ? "NULL" : r.shortComponentName,
3004                reason);
3005    }
3006
3007    @Override
3008    public void setFocusedStack(int stackId) {
3009        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3010        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3011        final long callingId = Binder.clearCallingIdentity();
3012        try {
3013            synchronized (this) {
3014                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3015                if (stack == null) {
3016                    return;
3017                }
3018                final ActivityRecord r = stack.topRunningActivityLocked();
3019                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3020                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3021                }
3022            }
3023        } finally {
3024            Binder.restoreCallingIdentity(callingId);
3025        }
3026    }
3027
3028    @Override
3029    public void setFocusedTask(int taskId) {
3030        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3031        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3032        final long callingId = Binder.clearCallingIdentity();
3033        try {
3034            synchronized (this) {
3035                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3036                if (task == null) {
3037                    return;
3038                }
3039                final ActivityRecord r = task.topRunningActivityLocked();
3040                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3041                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3042                }
3043            }
3044        } finally {
3045            Binder.restoreCallingIdentity(callingId);
3046        }
3047    }
3048
3049    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3050    @Override
3051    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3052        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3053        mTaskChangeNotificationController.registerTaskStackListener(listener);
3054    }
3055
3056    /**
3057     * Unregister a task stack listener so that it stops receiving callbacks.
3058     */
3059    @Override
3060    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3061         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3062         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3063     }
3064
3065    @Override
3066    public void notifyActivityDrawn(IBinder token) {
3067        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3068        synchronized (this) {
3069            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3070            if (r != null) {
3071                r.getStack().notifyActivityDrawnLocked(r);
3072            }
3073        }
3074    }
3075
3076    final void applyUpdateLockStateLocked(ActivityRecord r) {
3077        // Modifications to the UpdateLock state are done on our handler, outside
3078        // the activity manager's locks.  The new state is determined based on the
3079        // state *now* of the relevant activity record.  The object is passed to
3080        // the handler solely for logging detail, not to be consulted/modified.
3081        final boolean nextState = r != null && r.immersive;
3082        mHandler.sendMessage(
3083                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3084    }
3085
3086    final void applyUpdateVrModeLocked(ActivityRecord r) {
3087        mHandler.sendMessage(
3088                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3089    }
3090
3091    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3092        mHandler.sendMessage(
3093                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3094    }
3095
3096    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3097        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3098        if (vrService == null) {
3099            return;
3100        }
3101        vrService.onSleepStateChanged(isSleeping);
3102    }
3103
3104    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3105        Message msg = Message.obtain();
3106        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3107        msg.obj = r.task.askedCompatMode ? null : r;
3108        mUiHandler.sendMessage(msg);
3109    }
3110
3111    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3112        final Configuration globalConfig = getGlobalConfiguration();
3113        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3114                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3115            final Message msg = Message.obtain();
3116            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3117            msg.obj = r;
3118            mUiHandler.sendMessage(msg);
3119        }
3120    }
3121
3122    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3123            String what, Object obj, ProcessRecord srcApp) {
3124        app.lastActivityTime = now;
3125
3126        if (app.activities.size() > 0) {
3127            // Don't want to touch dependent processes that are hosting activities.
3128            return index;
3129        }
3130
3131        int lrui = mLruProcesses.lastIndexOf(app);
3132        if (lrui < 0) {
3133            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3134                    + what + " " + obj + " from " + srcApp);
3135            return index;
3136        }
3137
3138        if (lrui >= index) {
3139            // Don't want to cause this to move dependent processes *back* in the
3140            // list as if they were less frequently used.
3141            return index;
3142        }
3143
3144        if (lrui >= mLruProcessActivityStart) {
3145            // Don't want to touch dependent processes that are hosting activities.
3146            return index;
3147        }
3148
3149        mLruProcesses.remove(lrui);
3150        if (index > 0) {
3151            index--;
3152        }
3153        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3154                + " in LRU list: " + app);
3155        mLruProcesses.add(index, app);
3156        return index;
3157    }
3158
3159    static void killProcessGroup(int uid, int pid) {
3160        if (sKillHandler != null) {
3161            sKillHandler.sendMessage(
3162                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3163        } else {
3164            Slog.w(TAG, "Asked to kill process group before system bringup!");
3165            Process.killProcessGroup(uid, pid);
3166        }
3167    }
3168
3169    final void removeLruProcessLocked(ProcessRecord app) {
3170        int lrui = mLruProcesses.lastIndexOf(app);
3171        if (lrui >= 0) {
3172            if (!app.killed) {
3173                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3174                Process.killProcessQuiet(app.pid);
3175                killProcessGroup(app.uid, app.pid);
3176            }
3177            if (lrui <= mLruProcessActivityStart) {
3178                mLruProcessActivityStart--;
3179            }
3180            if (lrui <= mLruProcessServiceStart) {
3181                mLruProcessServiceStart--;
3182            }
3183            mLruProcesses.remove(lrui);
3184        }
3185    }
3186
3187    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3188            ProcessRecord client) {
3189        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3190                || app.treatLikeActivity;
3191        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3192        if (!activityChange && hasActivity) {
3193            // The process has activities, so we are only allowing activity-based adjustments
3194            // to move it.  It should be kept in the front of the list with other
3195            // processes that have activities, and we don't want those to change their
3196            // order except due to activity operations.
3197            return;
3198        }
3199
3200        mLruSeq++;
3201        final long now = SystemClock.uptimeMillis();
3202        app.lastActivityTime = now;
3203
3204        // First a quick reject: if the app is already at the position we will
3205        // put it, then there is nothing to do.
3206        if (hasActivity) {
3207            final int N = mLruProcesses.size();
3208            if (N > 0 && mLruProcesses.get(N-1) == app) {
3209                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3210                return;
3211            }
3212        } else {
3213            if (mLruProcessServiceStart > 0
3214                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3215                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3216                return;
3217            }
3218        }
3219
3220        int lrui = mLruProcesses.lastIndexOf(app);
3221
3222        if (app.persistent && lrui >= 0) {
3223            // We don't care about the position of persistent processes, as long as
3224            // they are in the list.
3225            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3226            return;
3227        }
3228
3229        /* In progress: compute new position first, so we can avoid doing work
3230           if the process is not actually going to move.  Not yet working.
3231        int addIndex;
3232        int nextIndex;
3233        boolean inActivity = false, inService = false;
3234        if (hasActivity) {
3235            // Process has activities, put it at the very tipsy-top.
3236            addIndex = mLruProcesses.size();
3237            nextIndex = mLruProcessServiceStart;
3238            inActivity = true;
3239        } else if (hasService) {
3240            // Process has services, put it at the top of the service list.
3241            addIndex = mLruProcessActivityStart;
3242            nextIndex = mLruProcessServiceStart;
3243            inActivity = true;
3244            inService = true;
3245        } else  {
3246            // Process not otherwise of interest, it goes to the top of the non-service area.
3247            addIndex = mLruProcessServiceStart;
3248            if (client != null) {
3249                int clientIndex = mLruProcesses.lastIndexOf(client);
3250                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3251                        + app);
3252                if (clientIndex >= 0 && addIndex > clientIndex) {
3253                    addIndex = clientIndex;
3254                }
3255            }
3256            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3257        }
3258
3259        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3260                + mLruProcessActivityStart + "): " + app);
3261        */
3262
3263        if (lrui >= 0) {
3264            if (lrui < mLruProcessActivityStart) {
3265                mLruProcessActivityStart--;
3266            }
3267            if (lrui < mLruProcessServiceStart) {
3268                mLruProcessServiceStart--;
3269            }
3270            /*
3271            if (addIndex > lrui) {
3272                addIndex--;
3273            }
3274            if (nextIndex > lrui) {
3275                nextIndex--;
3276            }
3277            */
3278            mLruProcesses.remove(lrui);
3279        }
3280
3281        /*
3282        mLruProcesses.add(addIndex, app);
3283        if (inActivity) {
3284            mLruProcessActivityStart++;
3285        }
3286        if (inService) {
3287            mLruProcessActivityStart++;
3288        }
3289        */
3290
3291        int nextIndex;
3292        if (hasActivity) {
3293            final int N = mLruProcesses.size();
3294            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3295                // Process doesn't have activities, but has clients with
3296                // activities...  move it up, but one below the top (the top
3297                // should always have a real activity).
3298                if (DEBUG_LRU) Slog.d(TAG_LRU,
3299                        "Adding to second-top of LRU activity list: " + app);
3300                mLruProcesses.add(N - 1, app);
3301                // To keep it from spamming the LRU list (by making a bunch of clients),
3302                // we will push down any other entries owned by the app.
3303                final int uid = app.info.uid;
3304                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3305                    ProcessRecord subProc = mLruProcesses.get(i);
3306                    if (subProc.info.uid == uid) {
3307                        // We want to push this one down the list.  If the process after
3308                        // it is for the same uid, however, don't do so, because we don't
3309                        // want them internally to be re-ordered.
3310                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3311                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3312                                    "Pushing uid " + uid + " swapping at " + i + ": "
3313                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3314                            ProcessRecord tmp = mLruProcesses.get(i);
3315                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3316                            mLruProcesses.set(i - 1, tmp);
3317                            i--;
3318                        }
3319                    } else {
3320                        // A gap, we can stop here.
3321                        break;
3322                    }
3323                }
3324            } else {
3325                // Process has activities, put it at the very tipsy-top.
3326                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3327                mLruProcesses.add(app);
3328            }
3329            nextIndex = mLruProcessServiceStart;
3330        } else if (hasService) {
3331            // Process has services, put it at the top of the service list.
3332            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3333            mLruProcesses.add(mLruProcessActivityStart, app);
3334            nextIndex = mLruProcessServiceStart;
3335            mLruProcessActivityStart++;
3336        } else  {
3337            // Process not otherwise of interest, it goes to the top of the non-service area.
3338            int index = mLruProcessServiceStart;
3339            if (client != null) {
3340                // If there is a client, don't allow the process to be moved up higher
3341                // in the list than that client.
3342                int clientIndex = mLruProcesses.lastIndexOf(client);
3343                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3344                        + " when updating " + app);
3345                if (clientIndex <= lrui) {
3346                    // Don't allow the client index restriction to push it down farther in the
3347                    // list than it already is.
3348                    clientIndex = lrui;
3349                }
3350                if (clientIndex >= 0 && index > clientIndex) {
3351                    index = clientIndex;
3352                }
3353            }
3354            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3355            mLruProcesses.add(index, app);
3356            nextIndex = index-1;
3357            mLruProcessActivityStart++;
3358            mLruProcessServiceStart++;
3359        }
3360
3361        // If the app is currently using a content provider or service,
3362        // bump those processes as well.
3363        for (int j=app.connections.size()-1; j>=0; j--) {
3364            ConnectionRecord cr = app.connections.valueAt(j);
3365            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3366                    && cr.binding.service.app != null
3367                    && cr.binding.service.app.lruSeq != mLruSeq
3368                    && !cr.binding.service.app.persistent) {
3369                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3370                        "service connection", cr, app);
3371            }
3372        }
3373        for (int j=app.conProviders.size()-1; j>=0; j--) {
3374            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3375            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3376                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3377                        "provider reference", cpr, app);
3378            }
3379        }
3380    }
3381
3382    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3383        if (uid == Process.SYSTEM_UID) {
3384            // The system gets to run in any process.  If there are multiple
3385            // processes with the same uid, just pick the first (this
3386            // should never happen).
3387            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3388            if (procs == null) return null;
3389            final int procCount = procs.size();
3390            for (int i = 0; i < procCount; i++) {
3391                final int procUid = procs.keyAt(i);
3392                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3393                    // Don't use an app process or different user process for system component.
3394                    continue;
3395                }
3396                return procs.valueAt(i);
3397            }
3398        }
3399        ProcessRecord proc = mProcessNames.get(processName, uid);
3400        if (false && proc != null && !keepIfLarge
3401                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3402                && proc.lastCachedPss >= 4000) {
3403            // Turn this condition on to cause killing to happen regularly, for testing.
3404            if (proc.baseProcessTracker != null) {
3405                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3406            }
3407            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3408        } else if (proc != null && !keepIfLarge
3409                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3410                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3411            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3412            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3413                if (proc.baseProcessTracker != null) {
3414                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3415                }
3416                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3417            }
3418        }
3419        return proc;
3420    }
3421
3422    void notifyPackageUse(String packageName, int reason) {
3423        IPackageManager pm = AppGlobals.getPackageManager();
3424        try {
3425            pm.notifyPackageUse(packageName, reason);
3426        } catch (RemoteException e) {
3427        }
3428    }
3429
3430    boolean isNextTransitionForward() {
3431        int transit = mWindowManager.getPendingAppTransition();
3432        return transit == TRANSIT_ACTIVITY_OPEN
3433                || transit == TRANSIT_TASK_OPEN
3434                || transit == TRANSIT_TASK_TO_FRONT;
3435    }
3436
3437    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3438            String processName, String abiOverride, int uid, Runnable crashHandler) {
3439        synchronized(this) {
3440            ApplicationInfo info = new ApplicationInfo();
3441            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3442            // For isolated processes, the former contains the parent's uid and the latter the
3443            // actual uid of the isolated process.
3444            // In the special case introduced by this method (which is, starting an isolated
3445            // process directly from the SystemServer without an actual parent app process) the
3446            // closest thing to a parent's uid is SYSTEM_UID.
3447            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3448            // the |isolated| logic in the ProcessRecord constructor.
3449            info.uid = Process.SYSTEM_UID;
3450            info.processName = processName;
3451            info.className = entryPoint;
3452            info.packageName = "android";
3453            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3454                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3455                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3456                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3457                    crashHandler);
3458            return proc != null ? proc.pid : 0;
3459        }
3460    }
3461
3462    final ProcessRecord startProcessLocked(String processName,
3463            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3464            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3465            boolean isolated, boolean keepIfLarge) {
3466        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3467                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3468                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3469                null /* crashHandler */);
3470    }
3471
3472    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3473            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3474            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3475            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3476        long startTime = SystemClock.elapsedRealtime();
3477        ProcessRecord app;
3478        if (!isolated) {
3479            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3480            checkTime(startTime, "startProcess: after getProcessRecord");
3481
3482            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3483                // If we are in the background, then check to see if this process
3484                // is bad.  If so, we will just silently fail.
3485                if (mAppErrors.isBadProcessLocked(info)) {
3486                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3487                            + "/" + info.processName);
3488                    return null;
3489                }
3490            } else {
3491                // When the user is explicitly starting a process, then clear its
3492                // crash count so that we won't make it bad until they see at
3493                // least one crash dialog again, and make the process good again
3494                // if it had been bad.
3495                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3496                        + "/" + info.processName);
3497                mAppErrors.resetProcessCrashTimeLocked(info);
3498                if (mAppErrors.isBadProcessLocked(info)) {
3499                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3500                            UserHandle.getUserId(info.uid), info.uid,
3501                            info.processName);
3502                    mAppErrors.clearBadProcessLocked(info);
3503                    if (app != null) {
3504                        app.bad = false;
3505                    }
3506                }
3507            }
3508        } else {
3509            // If this is an isolated process, it can't re-use an existing process.
3510            app = null;
3511        }
3512
3513        // We don't have to do anything more if:
3514        // (1) There is an existing application record; and
3515        // (2) The caller doesn't think it is dead, OR there is no thread
3516        //     object attached to it so we know it couldn't have crashed; and
3517        // (3) There is a pid assigned to it, so it is either starting or
3518        //     already running.
3519        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3520                + " app=" + app + " knownToBeDead=" + knownToBeDead
3521                + " thread=" + (app != null ? app.thread : null)
3522                + " pid=" + (app != null ? app.pid : -1));
3523        if (app != null && app.pid > 0) {
3524            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3525                // We already have the app running, or are waiting for it to
3526                // come up (we have a pid but not yet its thread), so keep it.
3527                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3528                // If this is a new package in the process, add the package to the list
3529                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3530                checkTime(startTime, "startProcess: done, added package to proc");
3531                return app;
3532            }
3533
3534            // An application record is attached to a previous process,
3535            // clean it up now.
3536            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3537            checkTime(startTime, "startProcess: bad proc running, killing");
3538            killProcessGroup(app.uid, app.pid);
3539            handleAppDiedLocked(app, true, true);
3540            checkTime(startTime, "startProcess: done killing old proc");
3541        }
3542
3543        String hostingNameStr = hostingName != null
3544                ? hostingName.flattenToShortString() : null;
3545
3546        if (app == null) {
3547            checkTime(startTime, "startProcess: creating new process record");
3548            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3549            if (app == null) {
3550                Slog.w(TAG, "Failed making new process record for "
3551                        + processName + "/" + info.uid + " isolated=" + isolated);
3552                return null;
3553            }
3554            app.crashHandler = crashHandler;
3555            checkTime(startTime, "startProcess: done creating new process record");
3556        } else {
3557            // If this is a new package in the process, add the package to the list
3558            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3559            checkTime(startTime, "startProcess: added package to existing proc");
3560        }
3561
3562        // If the system is not ready yet, then hold off on starting this
3563        // process until it is.
3564        if (!mProcessesReady
3565                && !isAllowedWhileBooting(info)
3566                && !allowWhileBooting) {
3567            if (!mProcessesOnHold.contains(app)) {
3568                mProcessesOnHold.add(app);
3569            }
3570            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3571                    "System not ready, putting on hold: " + app);
3572            checkTime(startTime, "startProcess: returning with proc on hold");
3573            return app;
3574        }
3575
3576        checkTime(startTime, "startProcess: stepping in to startProcess");
3577        startProcessLocked(
3578                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3579        checkTime(startTime, "startProcess: done starting proc!");
3580        return (app.pid != 0) ? app : null;
3581    }
3582
3583    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3584        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3585    }
3586
3587    private final void startProcessLocked(ProcessRecord app,
3588            String hostingType, String hostingNameStr) {
3589        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3590                null /* entryPoint */, null /* entryPointArgs */);
3591    }
3592
3593    private final void startProcessLocked(ProcessRecord app, String hostingType,
3594            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3595        long startTime = SystemClock.elapsedRealtime();
3596        if (app.pid > 0 && app.pid != MY_PID) {
3597            checkTime(startTime, "startProcess: removing from pids map");
3598            synchronized (mPidsSelfLocked) {
3599                mPidsSelfLocked.remove(app.pid);
3600                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3601            }
3602            checkTime(startTime, "startProcess: done removing from pids map");
3603            app.setPid(0);
3604        }
3605
3606        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3607                "startProcessLocked removing on hold: " + app);
3608        mProcessesOnHold.remove(app);
3609
3610        checkTime(startTime, "startProcess: starting to update cpu stats");
3611        updateCpuStats();
3612        checkTime(startTime, "startProcess: done updating cpu stats");
3613
3614        try {
3615            try {
3616                final int userId = UserHandle.getUserId(app.uid);
3617                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3618            } catch (RemoteException e) {
3619                throw e.rethrowAsRuntimeException();
3620            }
3621
3622            int uid = app.uid;
3623            int[] gids = null;
3624            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3625            if (!app.isolated) {
3626                int[] permGids = null;
3627                try {
3628                    checkTime(startTime, "startProcess: getting gids from package manager");
3629                    final IPackageManager pm = AppGlobals.getPackageManager();
3630                    permGids = pm.getPackageGids(app.info.packageName,
3631                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3632                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3633                            StorageManagerInternal.class);
3634                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3635                            app.info.packageName);
3636                } catch (RemoteException e) {
3637                    throw e.rethrowAsRuntimeException();
3638                }
3639
3640                /*
3641                 * Add shared application and profile GIDs so applications can share some
3642                 * resources like shared libraries and access user-wide resources
3643                 */
3644                if (ArrayUtils.isEmpty(permGids)) {
3645                    gids = new int[3];
3646                } else {
3647                    gids = new int[permGids.length + 3];
3648                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3649                }
3650                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3651                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3652                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3653            }
3654            checkTime(startTime, "startProcess: building args");
3655            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3656                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3657                        && mTopComponent != null
3658                        && app.processName.equals(mTopComponent.getPackageName())) {
3659                    uid = 0;
3660                }
3661                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3662                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3663                    uid = 0;
3664                }
3665            }
3666            int debugFlags = 0;
3667            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3668                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3669                // Also turn on CheckJNI for debuggable apps. It's quite
3670                // awkward to turn on otherwise.
3671                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3672            }
3673            // Run the app in safe mode if its manifest requests so or the
3674            // system is booted in safe mode.
3675            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3676                mSafeMode == true) {
3677                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3678            }
3679            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3680                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3681            }
3682            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3683            if ("true".equals(genDebugInfoProperty)) {
3684                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3685            }
3686            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3687                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3688            }
3689            if ("1".equals(SystemProperties.get("debug.assert"))) {
3690                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3691            }
3692            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3693                // Enable all debug flags required by the native debugger.
3694                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3695                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3696                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3697                mNativeDebuggingApp = null;
3698            }
3699
3700            String invokeWith = null;
3701            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3702                // Debuggable apps may include a wrapper script with their library directory.
3703                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3704                if (new File(wrapperFileName).exists()) {
3705                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3706                }
3707            }
3708
3709            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3710            if (requiredAbi == null) {
3711                requiredAbi = Build.SUPPORTED_ABIS[0];
3712            }
3713
3714            String instructionSet = null;
3715            if (app.info.primaryCpuAbi != null) {
3716                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3717            }
3718
3719            app.gids = gids;
3720            app.requiredAbi = requiredAbi;
3721            app.instructionSet = instructionSet;
3722
3723            // Start the process.  It will either succeed and return a result containing
3724            // the PID of the new process, or else throw a RuntimeException.
3725            boolean isActivityProcess = (entryPoint == null);
3726            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3727            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3728                    app.processName);
3729            checkTime(startTime, "startProcess: asking zygote to start proc");
3730            Process.ProcessStartResult startResult;
3731            if (hostingType.equals("webview_service")) {
3732                startResult = Process.startWebView(entryPoint,
3733                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3734                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3735                        app.info.dataDir, null, entryPointArgs);
3736            } else {
3737                startResult = Process.start(entryPoint,
3738                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3739                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3740                        app.info.dataDir, invokeWith, entryPointArgs);
3741            }
3742            checkTime(startTime, "startProcess: returned from zygote!");
3743            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3744
3745            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3746            checkTime(startTime, "startProcess: done updating battery stats");
3747
3748            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3749                    UserHandle.getUserId(uid), startResult.pid, uid,
3750                    app.processName, hostingType,
3751                    hostingNameStr != null ? hostingNameStr : "");
3752
3753            try {
3754                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3755                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3756            } catch (RemoteException ex) {
3757                // Ignore
3758            }
3759
3760            if (app.persistent) {
3761                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3762            }
3763
3764            checkTime(startTime, "startProcess: building log message");
3765            StringBuilder buf = mStringBuilder;
3766            buf.setLength(0);
3767            buf.append("Start proc ");
3768            buf.append(startResult.pid);
3769            buf.append(':');
3770            buf.append(app.processName);
3771            buf.append('/');
3772            UserHandle.formatUid(buf, uid);
3773            if (!isActivityProcess) {
3774                buf.append(" [");
3775                buf.append(entryPoint);
3776                buf.append("]");
3777            }
3778            buf.append(" for ");
3779            buf.append(hostingType);
3780            if (hostingNameStr != null) {
3781                buf.append(" ");
3782                buf.append(hostingNameStr);
3783            }
3784            Slog.i(TAG, buf.toString());
3785            app.setPid(startResult.pid);
3786            app.usingWrapper = startResult.usingWrapper;
3787            app.removed = false;
3788            app.killed = false;
3789            app.killedByAm = false;
3790            checkTime(startTime, "startProcess: starting to update pids map");
3791            ProcessRecord oldApp;
3792            synchronized (mPidsSelfLocked) {
3793                oldApp = mPidsSelfLocked.get(startResult.pid);
3794            }
3795            // If there is already an app occupying that pid that hasn't been cleaned up
3796            if (oldApp != null && !app.isolated) {
3797                // Clean up anything relating to this pid first
3798                Slog.w(TAG, "Reusing pid " + startResult.pid
3799                        + " while app is still mapped to it");
3800                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3801                        true /*replacingPid*/);
3802            }
3803            synchronized (mPidsSelfLocked) {
3804                this.mPidsSelfLocked.put(startResult.pid, app);
3805                if (isActivityProcess) {
3806                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3807                    msg.obj = app;
3808                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3809                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3810                }
3811            }
3812            checkTime(startTime, "startProcess: done updating pids map");
3813        } catch (RuntimeException e) {
3814            Slog.e(TAG, "Failure starting process " + app.processName, e);
3815
3816            // Something went very wrong while trying to start this process; one
3817            // common case is when the package is frozen due to an active
3818            // upgrade. To recover, clean up any active bookkeeping related to
3819            // starting this process. (We already invoked this method once when
3820            // the package was initially frozen through KILL_APPLICATION_MSG, so
3821            // it doesn't hurt to use it again.)
3822            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3823                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3824        }
3825    }
3826
3827    void updateUsageStats(ActivityRecord component, boolean resumed) {
3828        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3829                "updateUsageStats: comp=" + component + "res=" + resumed);
3830        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3831        if (resumed) {
3832            if (mUsageStatsService != null) {
3833                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3834                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3835            }
3836            synchronized (stats) {
3837                stats.noteActivityResumedLocked(component.app.uid);
3838            }
3839        } else {
3840            if (mUsageStatsService != null) {
3841                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3842                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3843            }
3844            synchronized (stats) {
3845                stats.noteActivityPausedLocked(component.app.uid);
3846            }
3847        }
3848    }
3849
3850    Intent getHomeIntent() {
3851        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3852        intent.setComponent(mTopComponent);
3853        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3854        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3855            intent.addCategory(Intent.CATEGORY_HOME);
3856        }
3857        return intent;
3858    }
3859
3860    boolean startHomeActivityLocked(int userId, String reason) {
3861        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3862                && mTopAction == null) {
3863            // We are running in factory test mode, but unable to find
3864            // the factory test app, so just sit around displaying the
3865            // error message and don't try to start anything.
3866            return false;
3867        }
3868        Intent intent = getHomeIntent();
3869        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3870        if (aInfo != null) {
3871            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3872            // Don't do this if the home app is currently being
3873            // instrumented.
3874            aInfo = new ActivityInfo(aInfo);
3875            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3876            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3877                    aInfo.applicationInfo.uid, true);
3878            if (app == null || app.instrumentationClass == null) {
3879                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3880                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3881            }
3882        } else {
3883            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3884        }
3885
3886        return true;
3887    }
3888
3889    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3890        ActivityInfo ai = null;
3891        ComponentName comp = intent.getComponent();
3892        try {
3893            if (comp != null) {
3894                // Factory test.
3895                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3896            } else {
3897                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3898                        intent,
3899                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3900                        flags, userId);
3901
3902                if (info != null) {
3903                    ai = info.activityInfo;
3904                }
3905            }
3906        } catch (RemoteException e) {
3907            // ignore
3908        }
3909
3910        return ai;
3911    }
3912
3913    /**
3914     * Starts the "new version setup screen" if appropriate.
3915     */
3916    void startSetupActivityLocked() {
3917        // Only do this once per boot.
3918        if (mCheckedForSetup) {
3919            return;
3920        }
3921
3922        // We will show this screen if the current one is a different
3923        // version than the last one shown, and we are not running in
3924        // low-level factory test mode.
3925        final ContentResolver resolver = mContext.getContentResolver();
3926        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3927                Settings.Global.getInt(resolver,
3928                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3929            mCheckedForSetup = true;
3930
3931            // See if we should be showing the platform update setup UI.
3932            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3933            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3934                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3935            if (!ris.isEmpty()) {
3936                final ResolveInfo ri = ris.get(0);
3937                String vers = ri.activityInfo.metaData != null
3938                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3939                        : null;
3940                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3941                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3942                            Intent.METADATA_SETUP_VERSION);
3943                }
3944                String lastVers = Settings.Secure.getString(
3945                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3946                if (vers != null && !vers.equals(lastVers)) {
3947                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3948                    intent.setComponent(new ComponentName(
3949                            ri.activityInfo.packageName, ri.activityInfo.name));
3950                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3951                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3952                            null, 0, 0, 0, null, false, false, null, null, null);
3953                }
3954            }
3955        }
3956    }
3957
3958    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3959        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3960    }
3961
3962    void enforceNotIsolatedCaller(String caller) {
3963        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3964            throw new SecurityException("Isolated process not allowed to call " + caller);
3965        }
3966    }
3967
3968    void enforceShellRestriction(String restriction, int userHandle) {
3969        if (Binder.getCallingUid() == Process.SHELL_UID) {
3970            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3971                throw new SecurityException("Shell does not have permission to access user "
3972                        + userHandle);
3973            }
3974        }
3975    }
3976
3977    @Override
3978    public int getFrontActivityScreenCompatMode() {
3979        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3980        synchronized (this) {
3981            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3982        }
3983    }
3984
3985    @Override
3986    public void setFrontActivityScreenCompatMode(int mode) {
3987        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3988                "setFrontActivityScreenCompatMode");
3989        synchronized (this) {
3990            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3991        }
3992    }
3993
3994    @Override
3995    public int getPackageScreenCompatMode(String packageName) {
3996        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3997        synchronized (this) {
3998            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3999        }
4000    }
4001
4002    @Override
4003    public void setPackageScreenCompatMode(String packageName, int mode) {
4004        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4005                "setPackageScreenCompatMode");
4006        synchronized (this) {
4007            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4008        }
4009    }
4010
4011    @Override
4012    public boolean getPackageAskScreenCompat(String packageName) {
4013        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4014        synchronized (this) {
4015            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4016        }
4017    }
4018
4019    @Override
4020    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4021        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4022                "setPackageAskScreenCompat");
4023        synchronized (this) {
4024            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4025        }
4026    }
4027
4028    private boolean hasUsageStatsPermission(String callingPackage) {
4029        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4030                Binder.getCallingUid(), callingPackage);
4031        if (mode == AppOpsManager.MODE_DEFAULT) {
4032            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4033                    == PackageManager.PERMISSION_GRANTED;
4034        }
4035        return mode == AppOpsManager.MODE_ALLOWED;
4036    }
4037
4038    @Override
4039    public int getPackageProcessState(String packageName, String callingPackage) {
4040        if (!hasUsageStatsPermission(callingPackage)) {
4041            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4042                    "getPackageProcessState");
4043        }
4044
4045        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4046        synchronized (this) {
4047            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4048                final ProcessRecord proc = mLruProcesses.get(i);
4049                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4050                        || procState > proc.setProcState) {
4051                    if (proc.pkgList.containsKey(packageName)) {
4052                        procState = proc.setProcState;
4053                        break;
4054                    }
4055                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
4056                        procState = proc.setProcState;
4057                    }
4058                }
4059            }
4060        }
4061        return procState;
4062    }
4063
4064    @Override
4065    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4066            throws RemoteException {
4067        synchronized (this) {
4068            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4069            if (app == null) {
4070                throw new IllegalArgumentException("Unknown process: " + process);
4071            }
4072            if (app.thread == null) {
4073                throw new IllegalArgumentException("Process has no app thread");
4074            }
4075            if (app.trimMemoryLevel >= level) {
4076                throw new IllegalArgumentException(
4077                        "Unable to set a higher trim level than current level");
4078            }
4079            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4080                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4081                throw new IllegalArgumentException("Unable to set a background trim level "
4082                    + "on a foreground process");
4083            }
4084            app.thread.scheduleTrimMemory(level);
4085            app.trimMemoryLevel = level;
4086            return true;
4087        }
4088    }
4089
4090    private void dispatchProcessesChanged() {
4091        int N;
4092        synchronized (this) {
4093            N = mPendingProcessChanges.size();
4094            if (mActiveProcessChanges.length < N) {
4095                mActiveProcessChanges = new ProcessChangeItem[N];
4096            }
4097            mPendingProcessChanges.toArray(mActiveProcessChanges);
4098            mPendingProcessChanges.clear();
4099            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4100                    "*** Delivering " + N + " process changes");
4101        }
4102
4103        int i = mProcessObservers.beginBroadcast();
4104        while (i > 0) {
4105            i--;
4106            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4107            if (observer != null) {
4108                try {
4109                    for (int j=0; j<N; j++) {
4110                        ProcessChangeItem item = mActiveProcessChanges[j];
4111                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4112                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4113                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4114                                    + item.uid + ": " + item.foregroundActivities);
4115                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4116                                    item.foregroundActivities);
4117                        }
4118                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4119                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4120                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4121                                    + ": " + item.processState);
4122                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4123                        }
4124                    }
4125                } catch (RemoteException e) {
4126                }
4127            }
4128        }
4129        mProcessObservers.finishBroadcast();
4130
4131        synchronized (this) {
4132            for (int j=0; j<N; j++) {
4133                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4134            }
4135        }
4136    }
4137
4138    private void dispatchProcessDied(int pid, int uid) {
4139        int i = mProcessObservers.beginBroadcast();
4140        while (i > 0) {
4141            i--;
4142            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4143            if (observer != null) {
4144                try {
4145                    observer.onProcessDied(pid, uid);
4146                } catch (RemoteException e) {
4147                }
4148            }
4149        }
4150        mProcessObservers.finishBroadcast();
4151    }
4152
4153    private void dispatchUidsChanged() {
4154        int N;
4155        synchronized (this) {
4156            N = mPendingUidChanges.size();
4157            if (mActiveUidChanges.length < N) {
4158                mActiveUidChanges = new UidRecord.ChangeItem[N];
4159            }
4160            for (int i=0; i<N; i++) {
4161                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4162                mActiveUidChanges[i] = change;
4163                if (change.uidRecord != null) {
4164                    change.uidRecord.pendingChange = null;
4165                    change.uidRecord = null;
4166                }
4167            }
4168            mPendingUidChanges.clear();
4169            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4170                    "*** Delivering " + N + " uid changes");
4171        }
4172
4173        int i = mUidObservers.beginBroadcast();
4174        while (i > 0) {
4175            i--;
4176            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4177            final UidObserverRegistration reg = (UidObserverRegistration)
4178                    mUidObservers.getBroadcastCookie(i);
4179            if (observer != null) {
4180                try {
4181                    for (int j=0; j<N; j++) {
4182                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4183                        final int change = item.change;
4184                        UidRecord validateUid = null;
4185                        if (VALIDATE_UID_STATES && i == 0) {
4186                            validateUid = mValidateUids.get(item.uid);
4187                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4188                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4189                                validateUid = new UidRecord(item.uid);
4190                                mValidateUids.put(item.uid, validateUid);
4191                            }
4192                        }
4193                        if (change == UidRecord.CHANGE_IDLE
4194                                || change == UidRecord.CHANGE_GONE_IDLE) {
4195                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4196                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4197                                        "UID idle uid=" + item.uid);
4198                                observer.onUidIdle(item.uid, item.ephemeral);
4199                            }
4200                            if (VALIDATE_UID_STATES && i == 0) {
4201                                if (validateUid != null) {
4202                                    validateUid.idle = true;
4203                                }
4204                            }
4205                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4206                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4207                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4208                                        "UID active uid=" + item.uid);
4209                                observer.onUidActive(item.uid);
4210                            }
4211                            if (VALIDATE_UID_STATES && i == 0) {
4212                                validateUid.idle = false;
4213                            }
4214                        }
4215                        if (change == UidRecord.CHANGE_GONE
4216                                || change == UidRecord.CHANGE_GONE_IDLE) {
4217                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4218                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4219                                        "UID gone uid=" + item.uid);
4220                                observer.onUidGone(item.uid, item.ephemeral);
4221                            }
4222                            if (reg.lastProcStates != null) {
4223                                reg.lastProcStates.delete(item.uid);
4224                            }
4225                            if (VALIDATE_UID_STATES && i == 0) {
4226                                if (validateUid != null) {
4227                                    mValidateUids.remove(item.uid);
4228                                }
4229                            }
4230                        } else {
4231                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4232                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4233                                        "UID CHANGED uid=" + item.uid
4234                                                + ": " + item.processState);
4235                                boolean doReport = true;
4236                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4237                                    final int lastState = reg.lastProcStates.get(item.uid,
4238                                            ActivityManager.PROCESS_STATE_UNKNOWN);
4239                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4240                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
4241                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
4242                                        doReport = lastAboveCut != newAboveCut;
4243                                    } else {
4244                                        doReport = item.processState
4245                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
4246                                    }
4247                                }
4248                                if (doReport) {
4249                                    if (reg.lastProcStates != null) {
4250                                        reg.lastProcStates.put(item.uid, item.processState);
4251                                    }
4252                                    observer.onUidStateChanged(item.uid, item.processState);
4253                                }
4254                            }
4255                            if (VALIDATE_UID_STATES && i == 0) {
4256                                validateUid.curProcState = validateUid.setProcState
4257                                        = item.processState;
4258                            }
4259                        }
4260                    }
4261                } catch (RemoteException e) {
4262                }
4263            }
4264        }
4265        mUidObservers.finishBroadcast();
4266
4267        synchronized (this) {
4268            for (int j=0; j<N; j++) {
4269                mAvailUidChanges.add(mActiveUidChanges[j]);
4270            }
4271        }
4272    }
4273
4274    @Override
4275    public final int startActivity(IApplicationThread caller, String callingPackage,
4276            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4277            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4278        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4279                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4280                UserHandle.getCallingUserId());
4281    }
4282
4283    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4284        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4285        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4286                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4287                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4288
4289        // TODO: Switch to user app stacks here.
4290        String mimeType = intent.getType();
4291        final Uri data = intent.getData();
4292        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4293            mimeType = getProviderMimeType(data, userId);
4294        }
4295        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4296
4297        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4298        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4299                null, 0, 0, null, null, null, null, false, userId, container, null);
4300    }
4301
4302    @Override
4303    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4304            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4305            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4306        enforceNotIsolatedCaller("startActivity");
4307        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4308                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4309        // TODO: Switch to user app stacks here.
4310        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4311                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4312                profilerInfo, null, null, bOptions, false, userId, null, null);
4313    }
4314
4315    @Override
4316    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4317            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4318            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4319            int userId) {
4320
4321        // This is very dangerous -- it allows you to perform a start activity (including
4322        // permission grants) as any app that may launch one of your own activities.  So
4323        // we will only allow this to be done from activities that are part of the core framework,
4324        // and then only when they are running as the system.
4325        final ActivityRecord sourceRecord;
4326        final int targetUid;
4327        final String targetPackage;
4328        synchronized (this) {
4329            if (resultTo == null) {
4330                throw new SecurityException("Must be called from an activity");
4331            }
4332            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4333            if (sourceRecord == null) {
4334                throw new SecurityException("Called with bad activity token: " + resultTo);
4335            }
4336            if (!sourceRecord.info.packageName.equals("android")) {
4337                throw new SecurityException(
4338                        "Must be called from an activity that is declared in the android package");
4339            }
4340            if (sourceRecord.app == null) {
4341                throw new SecurityException("Called without a process attached to activity");
4342            }
4343            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4344                // This is still okay, as long as this activity is running under the
4345                // uid of the original calling activity.
4346                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4347                    throw new SecurityException(
4348                            "Calling activity in uid " + sourceRecord.app.uid
4349                                    + " must be system uid or original calling uid "
4350                                    + sourceRecord.launchedFromUid);
4351                }
4352            }
4353            if (ignoreTargetSecurity) {
4354                if (intent.getComponent() == null) {
4355                    throw new SecurityException(
4356                            "Component must be specified with ignoreTargetSecurity");
4357                }
4358                if (intent.getSelector() != null) {
4359                    throw new SecurityException(
4360                            "Selector not allowed with ignoreTargetSecurity");
4361                }
4362            }
4363            targetUid = sourceRecord.launchedFromUid;
4364            targetPackage = sourceRecord.launchedFromPackage;
4365        }
4366
4367        if (userId == UserHandle.USER_NULL) {
4368            userId = UserHandle.getUserId(sourceRecord.app.uid);
4369        }
4370
4371        // TODO: Switch to user app stacks here.
4372        try {
4373            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4374                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4375                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4376            return ret;
4377        } catch (SecurityException e) {
4378            // XXX need to figure out how to propagate to original app.
4379            // A SecurityException here is generally actually a fault of the original
4380            // calling activity (such as a fairly granting permissions), so propagate it
4381            // back to them.
4382            /*
4383            StringBuilder msg = new StringBuilder();
4384            msg.append("While launching");
4385            msg.append(intent.toString());
4386            msg.append(": ");
4387            msg.append(e.getMessage());
4388            */
4389            throw e;
4390        }
4391    }
4392
4393    @Override
4394    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4395            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4396            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4397        enforceNotIsolatedCaller("startActivityAndWait");
4398        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4399                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4400        WaitResult res = new WaitResult();
4401        // TODO: Switch to user app stacks here.
4402        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4403                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4404                bOptions, false, userId, null, null);
4405        return res;
4406    }
4407
4408    @Override
4409    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4410            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4411            int startFlags, Configuration config, Bundle bOptions, int userId) {
4412        enforceNotIsolatedCaller("startActivityWithConfig");
4413        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4414                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4415        // TODO: Switch to user app stacks here.
4416        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4417                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4418                null, null, config, bOptions, false, userId, null, null);
4419        return ret;
4420    }
4421
4422    @Override
4423    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4424            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4425            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4426            throws TransactionTooLargeException {
4427        enforceNotIsolatedCaller("startActivityIntentSender");
4428        // Refuse possible leaked file descriptors
4429        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4430            throw new IllegalArgumentException("File descriptors passed in Intent");
4431        }
4432
4433        IIntentSender sender = intent.getTarget();
4434        if (!(sender instanceof PendingIntentRecord)) {
4435            throw new IllegalArgumentException("Bad PendingIntent object");
4436        }
4437
4438        PendingIntentRecord pir = (PendingIntentRecord)sender;
4439
4440        synchronized (this) {
4441            // If this is coming from the currently resumed activity, it is
4442            // effectively saying that app switches are allowed at this point.
4443            final ActivityStack stack = getFocusedStack();
4444            if (stack.mResumedActivity != null &&
4445                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4446                mAppSwitchesAllowedTime = 0;
4447            }
4448        }
4449        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4450                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4451        return ret;
4452    }
4453
4454    @Override
4455    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4456            Intent intent, String resolvedType, IVoiceInteractionSession session,
4457            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4458            Bundle bOptions, int userId) {
4459        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4460                != PackageManager.PERMISSION_GRANTED) {
4461            String msg = "Permission Denial: startVoiceActivity() from pid="
4462                    + Binder.getCallingPid()
4463                    + ", uid=" + Binder.getCallingUid()
4464                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4465            Slog.w(TAG, msg);
4466            throw new SecurityException(msg);
4467        }
4468        if (session == null || interactor == null) {
4469            throw new NullPointerException("null session or interactor");
4470        }
4471        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4472                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4473        // TODO: Switch to user app stacks here.
4474        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4475                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4476                null, bOptions, false, userId, null, null);
4477    }
4478
4479    @Override
4480    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4481            throws RemoteException {
4482        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4483        synchronized (this) {
4484            ActivityRecord activity = getFocusedStack().topActivity();
4485            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4486                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4487            }
4488            if (mRunningVoice != null || activity.task.voiceSession != null
4489                    || activity.voiceSession != null) {
4490                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4491                return;
4492            }
4493            if (activity.pendingVoiceInteractionStart) {
4494                Slog.w(TAG, "Pending start of voice interaction already.");
4495                return;
4496            }
4497            activity.pendingVoiceInteractionStart = true;
4498        }
4499        LocalServices.getService(VoiceInteractionManagerInternal.class)
4500                .startLocalVoiceInteraction(callingActivity, options);
4501    }
4502
4503    @Override
4504    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4505        LocalServices.getService(VoiceInteractionManagerInternal.class)
4506                .stopLocalVoiceInteraction(callingActivity);
4507    }
4508
4509    @Override
4510    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4511        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4512                .supportsLocalVoiceInteraction();
4513    }
4514
4515    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4516            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4517        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4518        if (activityToCallback == null) return;
4519        activityToCallback.setVoiceSessionLocked(voiceSession);
4520
4521        // Inform the activity
4522        try {
4523            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4524                    voiceInteractor);
4525            long token = Binder.clearCallingIdentity();
4526            try {
4527                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4528            } finally {
4529                Binder.restoreCallingIdentity(token);
4530            }
4531            // TODO: VI Should we cache the activity so that it's easier to find later
4532            // rather than scan through all the stacks and activities?
4533        } catch (RemoteException re) {
4534            activityToCallback.clearVoiceSessionLocked();
4535            // TODO: VI Should this terminate the voice session?
4536        }
4537    }
4538
4539    @Override
4540    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4541        synchronized (this) {
4542            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4543                if (keepAwake) {
4544                    mVoiceWakeLock.acquire();
4545                } else {
4546                    mVoiceWakeLock.release();
4547                }
4548            }
4549        }
4550    }
4551
4552    @Override
4553    public boolean startNextMatchingActivity(IBinder callingActivity,
4554            Intent intent, Bundle bOptions) {
4555        // Refuse possible leaked file descriptors
4556        if (intent != null && intent.hasFileDescriptors() == true) {
4557            throw new IllegalArgumentException("File descriptors passed in Intent");
4558        }
4559        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4560
4561        synchronized (this) {
4562            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4563            if (r == null) {
4564                ActivityOptions.abort(options);
4565                return false;
4566            }
4567            if (r.app == null || r.app.thread == null) {
4568                // The caller is not running...  d'oh!
4569                ActivityOptions.abort(options);
4570                return false;
4571            }
4572            intent = new Intent(intent);
4573            // The caller is not allowed to change the data.
4574            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4575            // And we are resetting to find the next component...
4576            intent.setComponent(null);
4577
4578            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4579
4580            ActivityInfo aInfo = null;
4581            try {
4582                List<ResolveInfo> resolves =
4583                    AppGlobals.getPackageManager().queryIntentActivities(
4584                            intent, r.resolvedType,
4585                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4586                            UserHandle.getCallingUserId()).getList();
4587
4588                // Look for the original activity in the list...
4589                final int N = resolves != null ? resolves.size() : 0;
4590                for (int i=0; i<N; i++) {
4591                    ResolveInfo rInfo = resolves.get(i);
4592                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4593                            && rInfo.activityInfo.name.equals(r.info.name)) {
4594                        // We found the current one...  the next matching is
4595                        // after it.
4596                        i++;
4597                        if (i<N) {
4598                            aInfo = resolves.get(i).activityInfo;
4599                        }
4600                        if (debug) {
4601                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4602                                    + "/" + r.info.name);
4603                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4604                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4605                        }
4606                        break;
4607                    }
4608                }
4609            } catch (RemoteException e) {
4610            }
4611
4612            if (aInfo == null) {
4613                // Nobody who is next!
4614                ActivityOptions.abort(options);
4615                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4616                return false;
4617            }
4618
4619            intent.setComponent(new ComponentName(
4620                    aInfo.applicationInfo.packageName, aInfo.name));
4621            intent.setFlags(intent.getFlags()&~(
4622                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4623                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4624                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4625                    Intent.FLAG_ACTIVITY_NEW_TASK));
4626
4627            // Okay now we need to start the new activity, replacing the
4628            // currently running activity.  This is a little tricky because
4629            // we want to start the new one as if the current one is finished,
4630            // but not finish the current one first so that there is no flicker.
4631            // And thus...
4632            final boolean wasFinishing = r.finishing;
4633            r.finishing = true;
4634
4635            // Propagate reply information over to the new activity.
4636            final ActivityRecord resultTo = r.resultTo;
4637            final String resultWho = r.resultWho;
4638            final int requestCode = r.requestCode;
4639            r.resultTo = null;
4640            if (resultTo != null) {
4641                resultTo.removeResultsLocked(r, resultWho, requestCode);
4642            }
4643
4644            final long origId = Binder.clearCallingIdentity();
4645            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4646                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4647                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4648                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4649                    false, false, null, null, null);
4650            Binder.restoreCallingIdentity(origId);
4651
4652            r.finishing = wasFinishing;
4653            if (res != ActivityManager.START_SUCCESS) {
4654                return false;
4655            }
4656            return true;
4657        }
4658    }
4659
4660    @Override
4661    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4662        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4663            String msg = "Permission Denial: startActivityFromRecents called without " +
4664                    START_TASKS_FROM_RECENTS;
4665            Slog.w(TAG, msg);
4666            throw new SecurityException(msg);
4667        }
4668        final long origId = Binder.clearCallingIdentity();
4669        try {
4670            synchronized (this) {
4671                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4672            }
4673        } finally {
4674            Binder.restoreCallingIdentity(origId);
4675        }
4676    }
4677
4678    final int startActivityInPackage(int uid, String callingPackage,
4679            Intent intent, String resolvedType, IBinder resultTo,
4680            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4681            IActivityContainer container, TaskRecord inTask) {
4682
4683        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4684                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4685
4686        // TODO: Switch to user app stacks here.
4687        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4688                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4689                null, null, null, bOptions, false, userId, container, inTask);
4690        return ret;
4691    }
4692
4693    @Override
4694    public final int startActivities(IApplicationThread caller, String callingPackage,
4695            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4696            int userId) {
4697        enforceNotIsolatedCaller("startActivities");
4698        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4699                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4700        // TODO: Switch to user app stacks here.
4701        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4702                resolvedTypes, resultTo, bOptions, userId);
4703        return ret;
4704    }
4705
4706    final int startActivitiesInPackage(int uid, String callingPackage,
4707            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4708            Bundle bOptions, int userId) {
4709
4710        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4711                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4712        // TODO: Switch to user app stacks here.
4713        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4714                resultTo, bOptions, userId);
4715        return ret;
4716    }
4717
4718    @Override
4719    public void reportActivityFullyDrawn(IBinder token) {
4720        synchronized (this) {
4721            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4722            if (r == null) {
4723                return;
4724            }
4725            r.reportFullyDrawnLocked();
4726        }
4727    }
4728
4729    @Override
4730    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4731        synchronized (this) {
4732            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4733            if (r == null) {
4734                return;
4735            }
4736            final long origId = Binder.clearCallingIdentity();
4737            try {
4738                r.setRequestedOrientation(requestedOrientation);
4739            } finally {
4740                Binder.restoreCallingIdentity(origId);
4741            }
4742        }
4743    }
4744
4745    @Override
4746    public int getRequestedOrientation(IBinder token) {
4747        synchronized (this) {
4748            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4749            if (r == null) {
4750                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4751            }
4752            return mWindowManager.getAppOrientation(r.appToken);
4753        }
4754    }
4755
4756    @Override
4757    public final void requestActivityRelaunch(IBinder token) {
4758        synchronized(this) {
4759            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4760            if (r == null) {
4761                return;
4762            }
4763            final long origId = Binder.clearCallingIdentity();
4764            try {
4765                r.forceNewConfig = true;
4766                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4767                        false /* preserveWindow */);
4768            } finally {
4769                Binder.restoreCallingIdentity(origId);
4770            }
4771        }
4772    }
4773
4774    /**
4775     * This is the internal entry point for handling Activity.finish().
4776     *
4777     * @param token The Binder token referencing the Activity we want to finish.
4778     * @param resultCode Result code, if any, from this Activity.
4779     * @param resultData Result data (Intent), if any, from this Activity.
4780     * @param finishTask Whether to finish the task associated with this Activity.
4781     *
4782     * @return Returns true if the activity successfully finished, or false if it is still running.
4783     */
4784    @Override
4785    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4786            int finishTask) {
4787        // Refuse possible leaked file descriptors
4788        if (resultData != null && resultData.hasFileDescriptors() == true) {
4789            throw new IllegalArgumentException("File descriptors passed in Intent");
4790        }
4791
4792        synchronized(this) {
4793            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4794            if (r == null) {
4795                return true;
4796            }
4797            // Keep track of the root activity of the task before we finish it
4798            TaskRecord tr = r.task;
4799            ActivityRecord rootR = tr.getRootActivity();
4800            if (rootR == null) {
4801                Slog.w(TAG, "Finishing task with all activities already finished");
4802            }
4803            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4804            // finish.
4805            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4806                    mStackSupervisor.isLastLockedTask(tr)) {
4807                Slog.i(TAG, "Not finishing task in lock task mode");
4808                mStackSupervisor.showLockTaskToast();
4809                return false;
4810            }
4811            if (mController != null) {
4812                // Find the first activity that is not finishing.
4813                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4814                if (next != null) {
4815                    // ask watcher if this is allowed
4816                    boolean resumeOK = true;
4817                    try {
4818                        resumeOK = mController.activityResuming(next.packageName);
4819                    } catch (RemoteException e) {
4820                        mController = null;
4821                        Watchdog.getInstance().setActivityController(null);
4822                    }
4823
4824                    if (!resumeOK) {
4825                        Slog.i(TAG, "Not finishing activity because controller resumed");
4826                        return false;
4827                    }
4828                }
4829            }
4830            final long origId = Binder.clearCallingIdentity();
4831            try {
4832                boolean res;
4833                final boolean finishWithRootActivity =
4834                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4835                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4836                        || (finishWithRootActivity && r == rootR)) {
4837                    // If requested, remove the task that is associated to this activity only if it
4838                    // was the root activity in the task. The result code and data is ignored
4839                    // because we don't support returning them across task boundaries. Also, to
4840                    // keep backwards compatibility we remove the task from recents when finishing
4841                    // task with root activity.
4842                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4843                    if (!res) {
4844                        Slog.i(TAG, "Removing task failed to finish activity");
4845                    }
4846                } else {
4847                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4848                            resultData, "app-request", true);
4849                    if (!res) {
4850                        Slog.i(TAG, "Failed to finish by app-request");
4851                    }
4852                }
4853                return res;
4854            } finally {
4855                Binder.restoreCallingIdentity(origId);
4856            }
4857        }
4858    }
4859
4860    @Override
4861    public final void finishHeavyWeightApp() {
4862        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4863                != PackageManager.PERMISSION_GRANTED) {
4864            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4865                    + Binder.getCallingPid()
4866                    + ", uid=" + Binder.getCallingUid()
4867                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4868            Slog.w(TAG, msg);
4869            throw new SecurityException(msg);
4870        }
4871
4872        synchronized(this) {
4873            if (mHeavyWeightProcess == null) {
4874                return;
4875            }
4876
4877            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4878            for (int i = 0; i < activities.size(); i++) {
4879                ActivityRecord r = activities.get(i);
4880                if (!r.finishing && r.isInStackLocked()) {
4881                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4882                            null, "finish-heavy", true);
4883                }
4884            }
4885
4886            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4887                    mHeavyWeightProcess.userId, 0));
4888            mHeavyWeightProcess = null;
4889        }
4890    }
4891
4892    @Override
4893    public void crashApplication(int uid, int initialPid, String packageName,
4894            String message) {
4895        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4896                != PackageManager.PERMISSION_GRANTED) {
4897            String msg = "Permission Denial: crashApplication() from pid="
4898                    + Binder.getCallingPid()
4899                    + ", uid=" + Binder.getCallingUid()
4900                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4901            Slog.w(TAG, msg);
4902            throw new SecurityException(msg);
4903        }
4904
4905        synchronized(this) {
4906            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4907        }
4908    }
4909
4910    @Override
4911    public final void finishSubActivity(IBinder token, String resultWho,
4912            int requestCode) {
4913        synchronized(this) {
4914            final long origId = Binder.clearCallingIdentity();
4915            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4916            if (r != null) {
4917                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4918            }
4919            Binder.restoreCallingIdentity(origId);
4920        }
4921    }
4922
4923    @Override
4924    public boolean finishActivityAffinity(IBinder token) {
4925        synchronized(this) {
4926            final long origId = Binder.clearCallingIdentity();
4927            try {
4928                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4929                if (r == null) {
4930                    return false;
4931                }
4932
4933                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4934                // can finish.
4935                final TaskRecord task = r.task;
4936                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4937                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4938                    mStackSupervisor.showLockTaskToast();
4939                    return false;
4940                }
4941                return task.getStack().finishActivityAffinityLocked(r);
4942            } finally {
4943                Binder.restoreCallingIdentity(origId);
4944            }
4945        }
4946    }
4947
4948    @Override
4949    public void finishVoiceTask(IVoiceInteractionSession session) {
4950        synchronized (this) {
4951            final long origId = Binder.clearCallingIdentity();
4952            try {
4953                // TODO: VI Consider treating local voice interactions and voice tasks
4954                // differently here
4955                mStackSupervisor.finishVoiceTask(session);
4956            } finally {
4957                Binder.restoreCallingIdentity(origId);
4958            }
4959        }
4960
4961    }
4962
4963    @Override
4964    public boolean releaseActivityInstance(IBinder token) {
4965        synchronized(this) {
4966            final long origId = Binder.clearCallingIdentity();
4967            try {
4968                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4969                if (r == null) {
4970                    return false;
4971                }
4972                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4973            } finally {
4974                Binder.restoreCallingIdentity(origId);
4975            }
4976        }
4977    }
4978
4979    @Override
4980    public void releaseSomeActivities(IApplicationThread appInt) {
4981        synchronized(this) {
4982            final long origId = Binder.clearCallingIdentity();
4983            try {
4984                ProcessRecord app = getRecordForAppLocked(appInt);
4985                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4986            } finally {
4987                Binder.restoreCallingIdentity(origId);
4988            }
4989        }
4990    }
4991
4992    @Override
4993    public boolean willActivityBeVisible(IBinder token) {
4994        synchronized(this) {
4995            ActivityStack stack = ActivityRecord.getStackLocked(token);
4996            if (stack != null) {
4997                return stack.willActivityBeVisibleLocked(token);
4998            }
4999            return false;
5000        }
5001    }
5002
5003    @Override
5004    public void overridePendingTransition(IBinder token, String packageName,
5005            int enterAnim, int exitAnim) {
5006        synchronized(this) {
5007            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5008            if (self == null) {
5009                return;
5010            }
5011
5012            final long origId = Binder.clearCallingIdentity();
5013
5014            if (self.state == ActivityState.RESUMED
5015                    || self.state == ActivityState.PAUSING) {
5016                mWindowManager.overridePendingAppTransition(packageName,
5017                        enterAnim, exitAnim, null);
5018            }
5019
5020            Binder.restoreCallingIdentity(origId);
5021        }
5022    }
5023
5024    /**
5025     * Main function for removing an existing process from the activity manager
5026     * as a result of that process going away.  Clears out all connections
5027     * to the process.
5028     */
5029    private final void handleAppDiedLocked(ProcessRecord app,
5030            boolean restarting, boolean allowRestart) {
5031        int pid = app.pid;
5032        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5033                false /*replacingPid*/);
5034        if (!kept && !restarting) {
5035            removeLruProcessLocked(app);
5036            if (pid > 0) {
5037                ProcessList.remove(pid);
5038            }
5039        }
5040
5041        if (mProfileProc == app) {
5042            clearProfilerLocked();
5043        }
5044
5045        // Remove this application's activities from active lists.
5046        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5047
5048        app.activities.clear();
5049
5050        if (app.instrumentationClass != null) {
5051            Slog.w(TAG, "Crash of app " + app.processName
5052                  + " running instrumentation " + app.instrumentationClass);
5053            Bundle info = new Bundle();
5054            info.putString("shortMsg", "Process crashed.");
5055            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5056        }
5057
5058        mWindowManager.deferSurfaceLayout();
5059        try {
5060            if (!restarting && hasVisibleActivities
5061                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5062                // If there was nothing to resume, and we are not already restarting this process, but
5063                // there is a visible activity that is hosted by the process...  then make sure all
5064                // visible activities are running, taking care of restarting this process.
5065                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5066            }
5067        } finally {
5068            mWindowManager.continueSurfaceLayout();
5069        }
5070    }
5071
5072    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5073        IBinder threadBinder = thread.asBinder();
5074        // Find the application record.
5075        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5076            ProcessRecord rec = mLruProcesses.get(i);
5077            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5078                return i;
5079            }
5080        }
5081        return -1;
5082    }
5083
5084    final ProcessRecord getRecordForAppLocked(
5085            IApplicationThread thread) {
5086        if (thread == null) {
5087            return null;
5088        }
5089
5090        int appIndex = getLRURecordIndexForAppLocked(thread);
5091        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5092    }
5093
5094    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5095        // If there are no longer any background processes running,
5096        // and the app that died was not running instrumentation,
5097        // then tell everyone we are now low on memory.
5098        boolean haveBg = false;
5099        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5100            ProcessRecord rec = mLruProcesses.get(i);
5101            if (rec.thread != null
5102                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5103                haveBg = true;
5104                break;
5105            }
5106        }
5107
5108        if (!haveBg) {
5109            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5110            if (doReport) {
5111                long now = SystemClock.uptimeMillis();
5112                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5113                    doReport = false;
5114                } else {
5115                    mLastMemUsageReportTime = now;
5116                }
5117            }
5118            final ArrayList<ProcessMemInfo> memInfos
5119                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5120            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5121            long now = SystemClock.uptimeMillis();
5122            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5123                ProcessRecord rec = mLruProcesses.get(i);
5124                if (rec == dyingProc || rec.thread == null) {
5125                    continue;
5126                }
5127                if (doReport) {
5128                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5129                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5130                }
5131                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5132                    // The low memory report is overriding any current
5133                    // state for a GC request.  Make sure to do
5134                    // heavy/important/visible/foreground processes first.
5135                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5136                        rec.lastRequestedGc = 0;
5137                    } else {
5138                        rec.lastRequestedGc = rec.lastLowMemory;
5139                    }
5140                    rec.reportLowMemory = true;
5141                    rec.lastLowMemory = now;
5142                    mProcessesToGc.remove(rec);
5143                    addProcessToGcListLocked(rec);
5144                }
5145            }
5146            if (doReport) {
5147                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5148                mHandler.sendMessage(msg);
5149            }
5150            scheduleAppGcsLocked();
5151        }
5152    }
5153
5154    final void appDiedLocked(ProcessRecord app) {
5155       appDiedLocked(app, app.pid, app.thread, false);
5156    }
5157
5158    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5159            boolean fromBinderDied) {
5160        // First check if this ProcessRecord is actually active for the pid.
5161        synchronized (mPidsSelfLocked) {
5162            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5163            if (curProc != app) {
5164                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5165                return;
5166            }
5167        }
5168
5169        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5170        synchronized (stats) {
5171            stats.noteProcessDiedLocked(app.info.uid, pid);
5172        }
5173
5174        if (!app.killed) {
5175            if (!fromBinderDied) {
5176                Process.killProcessQuiet(pid);
5177            }
5178            killProcessGroup(app.uid, pid);
5179            app.killed = true;
5180        }
5181
5182        // Clean up already done if the process has been re-started.
5183        if (app.pid == pid && app.thread != null &&
5184                app.thread.asBinder() == thread.asBinder()) {
5185            boolean doLowMem = app.instrumentationClass == null;
5186            boolean doOomAdj = doLowMem;
5187            if (!app.killedByAm) {
5188                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5189                        + ") has died");
5190                mAllowLowerMemLevel = true;
5191            } else {
5192                // Note that we always want to do oom adj to update our state with the
5193                // new number of procs.
5194                mAllowLowerMemLevel = false;
5195                doLowMem = false;
5196            }
5197            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5198            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5199                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5200            handleAppDiedLocked(app, false, true);
5201
5202            if (doOomAdj) {
5203                updateOomAdjLocked();
5204            }
5205            if (doLowMem) {
5206                doLowMemReportIfNeededLocked(app);
5207            }
5208        } else if (app.pid != pid) {
5209            // A new process has already been started.
5210            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5211                    + ") has died and restarted (pid " + app.pid + ").");
5212            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5213        } else if (DEBUG_PROCESSES) {
5214            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5215                    + thread.asBinder());
5216        }
5217    }
5218
5219    /**
5220     * If a stack trace dump file is configured, dump process stack traces.
5221     * @param clearTraces causes the dump file to be erased prior to the new
5222     *    traces being written, if true; when false, the new traces will be
5223     *    appended to any existing file content.
5224     * @param firstPids of dalvik VM processes to dump stack traces for first
5225     * @param lastPids of dalvik VM processes to dump stack traces for last
5226     * @param nativeProcs optional list of native process names to dump stack crawls
5227     * @return file containing stack traces, or null if no dump file is configured
5228     */
5229    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5230            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5231        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5232        if (tracesPath == null || tracesPath.length() == 0) {
5233            return null;
5234        }
5235
5236        File tracesFile = new File(tracesPath);
5237        try {
5238            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5239            tracesFile.createNewFile();
5240            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5241        } catch (IOException e) {
5242            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5243            return null;
5244        }
5245
5246        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5247        return tracesFile;
5248    }
5249
5250    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5251            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5252        // Use a FileObserver to detect when traces finish writing.
5253        // The order of traces is considered important to maintain for legibility.
5254        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5255            @Override
5256            public synchronized void onEvent(int event, String path) { notify(); }
5257        };
5258
5259        try {
5260            observer.startWatching();
5261
5262            // First collect all of the stacks of the most important pids.
5263            if (firstPids != null) {
5264                try {
5265                    int num = firstPids.size();
5266                    for (int i = 0; i < num; i++) {
5267                        synchronized (observer) {
5268                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5269                                    + firstPids.get(i));
5270                            final long sime = SystemClock.elapsedRealtime();
5271                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5272                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5273                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5274                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5275                        }
5276                    }
5277                } catch (InterruptedException e) {
5278                    Slog.wtf(TAG, e);
5279                }
5280            }
5281
5282            // Next collect the stacks of the native pids
5283            if (nativeProcs != null) {
5284                int[] pids = Process.getPidsForCommands(nativeProcs);
5285                if (pids != null) {
5286                    for (int pid : pids) {
5287                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5288                        final long sime = SystemClock.elapsedRealtime();
5289                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5290                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5291                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5292                    }
5293                }
5294            }
5295
5296            // Lastly, measure CPU usage.
5297            if (processCpuTracker != null) {
5298                processCpuTracker.init();
5299                System.gc();
5300                processCpuTracker.update();
5301                try {
5302                    synchronized (processCpuTracker) {
5303                        processCpuTracker.wait(500); // measure over 1/2 second.
5304                    }
5305                } catch (InterruptedException e) {
5306                }
5307                processCpuTracker.update();
5308
5309                // We'll take the stack crawls of just the top apps using CPU.
5310                final int N = processCpuTracker.countWorkingStats();
5311                int numProcs = 0;
5312                for (int i=0; i<N && numProcs<5; i++) {
5313                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5314                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5315                        numProcs++;
5316                        try {
5317                            synchronized (observer) {
5318                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5319                                        + stats.pid);
5320                                final long stime = SystemClock.elapsedRealtime();
5321                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5322                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5323                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5324                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5325                            }
5326                        } catch (InterruptedException e) {
5327                            Slog.wtf(TAG, e);
5328                        }
5329                    } else if (DEBUG_ANR) {
5330                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5331                                + stats.pid);
5332                    }
5333                }
5334            }
5335        } finally {
5336            observer.stopWatching();
5337        }
5338    }
5339
5340    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5341        if (true || IS_USER_BUILD) {
5342            return;
5343        }
5344        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5345        if (tracesPath == null || tracesPath.length() == 0) {
5346            return;
5347        }
5348
5349        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5350        StrictMode.allowThreadDiskWrites();
5351        try {
5352            final File tracesFile = new File(tracesPath);
5353            final File tracesDir = tracesFile.getParentFile();
5354            final File tracesTmp = new File(tracesDir, "__tmp__");
5355            try {
5356                if (tracesFile.exists()) {
5357                    tracesTmp.delete();
5358                    tracesFile.renameTo(tracesTmp);
5359                }
5360                StringBuilder sb = new StringBuilder();
5361                Time tobj = new Time();
5362                tobj.set(System.currentTimeMillis());
5363                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5364                sb.append(": ");
5365                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5366                sb.append(" since ");
5367                sb.append(msg);
5368                FileOutputStream fos = new FileOutputStream(tracesFile);
5369                fos.write(sb.toString().getBytes());
5370                if (app == null) {
5371                    fos.write("\n*** No application process!".getBytes());
5372                }
5373                fos.close();
5374                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5375            } catch (IOException e) {
5376                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5377                return;
5378            }
5379
5380            if (app != null) {
5381                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5382                firstPids.add(app.pid);
5383                dumpStackTraces(tracesPath, firstPids, null, null, null);
5384            }
5385
5386            File lastTracesFile = null;
5387            File curTracesFile = null;
5388            for (int i=9; i>=0; i--) {
5389                String name = String.format(Locale.US, "slow%02d.txt", i);
5390                curTracesFile = new File(tracesDir, name);
5391                if (curTracesFile.exists()) {
5392                    if (lastTracesFile != null) {
5393                        curTracesFile.renameTo(lastTracesFile);
5394                    } else {
5395                        curTracesFile.delete();
5396                    }
5397                }
5398                lastTracesFile = curTracesFile;
5399            }
5400            tracesFile.renameTo(curTracesFile);
5401            if (tracesTmp.exists()) {
5402                tracesTmp.renameTo(tracesFile);
5403            }
5404        } finally {
5405            StrictMode.setThreadPolicy(oldPolicy);
5406        }
5407    }
5408
5409    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5410        if (!mLaunchWarningShown) {
5411            mLaunchWarningShown = true;
5412            mUiHandler.post(new Runnable() {
5413                @Override
5414                public void run() {
5415                    synchronized (ActivityManagerService.this) {
5416                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5417                        d.show();
5418                        mUiHandler.postDelayed(new Runnable() {
5419                            @Override
5420                            public void run() {
5421                                synchronized (ActivityManagerService.this) {
5422                                    d.dismiss();
5423                                    mLaunchWarningShown = false;
5424                                }
5425                            }
5426                        }, 4000);
5427                    }
5428                }
5429            });
5430        }
5431    }
5432
5433    @Override
5434    public boolean clearApplicationUserData(final String packageName,
5435            final IPackageDataObserver observer, int userId) {
5436        enforceNotIsolatedCaller("clearApplicationUserData");
5437        int uid = Binder.getCallingUid();
5438        int pid = Binder.getCallingPid();
5439        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5440                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5441
5442
5443        long callingId = Binder.clearCallingIdentity();
5444        try {
5445            IPackageManager pm = AppGlobals.getPackageManager();
5446            int pkgUid = -1;
5447            synchronized(this) {
5448                if (getPackageManagerInternalLocked().isPackageDataProtected(
5449                        userId, packageName)) {
5450                    throw new SecurityException(
5451                            "Cannot clear data for a protected package: " + packageName);
5452                }
5453
5454                try {
5455                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5456                } catch (RemoteException e) {
5457                }
5458                if (pkgUid == -1) {
5459                    Slog.w(TAG, "Invalid packageName: " + packageName);
5460                    if (observer != null) {
5461                        try {
5462                            observer.onRemoveCompleted(packageName, false);
5463                        } catch (RemoteException e) {
5464                            Slog.i(TAG, "Observer no longer exists.");
5465                        }
5466                    }
5467                    return false;
5468                }
5469                if (uid == pkgUid || checkComponentPermission(
5470                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5471                        pid, uid, -1, true)
5472                        == PackageManager.PERMISSION_GRANTED) {
5473                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5474                } else {
5475                    throw new SecurityException("PID " + pid + " does not have permission "
5476                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5477                                    + " of package " + packageName);
5478                }
5479
5480                // Remove all tasks match the cleared application package and user
5481                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5482                    final TaskRecord tr = mRecentTasks.get(i);
5483                    final String taskPackageName =
5484                            tr.getBaseIntent().getComponent().getPackageName();
5485                    if (tr.userId != userId) continue;
5486                    if (!taskPackageName.equals(packageName)) continue;
5487                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5488                }
5489            }
5490
5491            final int pkgUidF = pkgUid;
5492            final int userIdF = userId;
5493            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5494                @Override
5495                public void onRemoveCompleted(String packageName, boolean succeeded)
5496                        throws RemoteException {
5497                    synchronized (ActivityManagerService.this) {
5498                        finishForceStopPackageLocked(packageName, pkgUidF);
5499                    }
5500
5501                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5502                            Uri.fromParts("package", packageName, null));
5503                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5504                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5505                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5506                            null, null, 0, null, null, null, null, false, false, userIdF);
5507
5508                    if (observer != null) {
5509                        observer.onRemoveCompleted(packageName, succeeded);
5510                    }
5511                }
5512            };
5513
5514            try {
5515                // Clear application user data
5516                pm.clearApplicationUserData(packageName, localObserver, userId);
5517
5518                synchronized(this) {
5519                    // Remove all permissions granted from/to this package
5520                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5521                }
5522
5523                // Remove all zen rules created by this package; revoke it's zen access.
5524                INotificationManager inm = NotificationManager.getService();
5525                inm.removeAutomaticZenRules(packageName);
5526                inm.setNotificationPolicyAccessGranted(packageName, false);
5527
5528            } catch (RemoteException e) {
5529            }
5530        } finally {
5531            Binder.restoreCallingIdentity(callingId);
5532        }
5533        return true;
5534    }
5535
5536    @Override
5537    public void killBackgroundProcesses(final String packageName, int userId) {
5538        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5539                != PackageManager.PERMISSION_GRANTED &&
5540                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5541                        != PackageManager.PERMISSION_GRANTED) {
5542            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5543                    + Binder.getCallingPid()
5544                    + ", uid=" + Binder.getCallingUid()
5545                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5546            Slog.w(TAG, msg);
5547            throw new SecurityException(msg);
5548        }
5549
5550        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5551                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5552        long callingId = Binder.clearCallingIdentity();
5553        try {
5554            IPackageManager pm = AppGlobals.getPackageManager();
5555            synchronized(this) {
5556                int appId = -1;
5557                try {
5558                    appId = UserHandle.getAppId(
5559                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5560                } catch (RemoteException e) {
5561                }
5562                if (appId == -1) {
5563                    Slog.w(TAG, "Invalid packageName: " + packageName);
5564                    return;
5565                }
5566                killPackageProcessesLocked(packageName, appId, userId,
5567                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5568            }
5569        } finally {
5570            Binder.restoreCallingIdentity(callingId);
5571        }
5572    }
5573
5574    @Override
5575    public void killAllBackgroundProcesses() {
5576        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5577                != PackageManager.PERMISSION_GRANTED) {
5578            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5579                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5580                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5581            Slog.w(TAG, msg);
5582            throw new SecurityException(msg);
5583        }
5584
5585        final long callingId = Binder.clearCallingIdentity();
5586        try {
5587            synchronized (this) {
5588                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5589                final int NP = mProcessNames.getMap().size();
5590                for (int ip = 0; ip < NP; ip++) {
5591                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5592                    final int NA = apps.size();
5593                    for (int ia = 0; ia < NA; ia++) {
5594                        final ProcessRecord app = apps.valueAt(ia);
5595                        if (app.persistent) {
5596                            // We don't kill persistent processes.
5597                            continue;
5598                        }
5599                        if (app.removed) {
5600                            procs.add(app);
5601                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5602                            app.removed = true;
5603                            procs.add(app);
5604                        }
5605                    }
5606                }
5607
5608                final int N = procs.size();
5609                for (int i = 0; i < N; i++) {
5610                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5611                }
5612
5613                mAllowLowerMemLevel = true;
5614
5615                updateOomAdjLocked();
5616                doLowMemReportIfNeededLocked(null);
5617            }
5618        } finally {
5619            Binder.restoreCallingIdentity(callingId);
5620        }
5621    }
5622
5623    /**
5624     * Kills all background processes, except those matching any of the
5625     * specified properties.
5626     *
5627     * @param minTargetSdk the target SDK version at or above which to preserve
5628     *                     processes, or {@code -1} to ignore the target SDK
5629     * @param maxProcState the process state at or below which to preserve
5630     *                     processes, or {@code -1} to ignore the process state
5631     */
5632    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5633        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5634                != PackageManager.PERMISSION_GRANTED) {
5635            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5636                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5637                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5638            Slog.w(TAG, msg);
5639            throw new SecurityException(msg);
5640        }
5641
5642        final long callingId = Binder.clearCallingIdentity();
5643        try {
5644            synchronized (this) {
5645                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5646                final int NP = mProcessNames.getMap().size();
5647                for (int ip = 0; ip < NP; ip++) {
5648                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5649                    final int NA = apps.size();
5650                    for (int ia = 0; ia < NA; ia++) {
5651                        final ProcessRecord app = apps.valueAt(ia);
5652                        if (app.removed) {
5653                            procs.add(app);
5654                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5655                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5656                            app.removed = true;
5657                            procs.add(app);
5658                        }
5659                    }
5660                }
5661
5662                final int N = procs.size();
5663                for (int i = 0; i < N; i++) {
5664                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5665                }
5666            }
5667        } finally {
5668            Binder.restoreCallingIdentity(callingId);
5669        }
5670    }
5671
5672    @Override
5673    public void forceStopPackage(final String packageName, int userId) {
5674        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5675                != PackageManager.PERMISSION_GRANTED) {
5676            String msg = "Permission Denial: forceStopPackage() from pid="
5677                    + Binder.getCallingPid()
5678                    + ", uid=" + Binder.getCallingUid()
5679                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5680            Slog.w(TAG, msg);
5681            throw new SecurityException(msg);
5682        }
5683        final int callingPid = Binder.getCallingPid();
5684        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5685                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5686        long callingId = Binder.clearCallingIdentity();
5687        try {
5688            IPackageManager pm = AppGlobals.getPackageManager();
5689            synchronized(this) {
5690                int[] users = userId == UserHandle.USER_ALL
5691                        ? mUserController.getUsers() : new int[] { userId };
5692                for (int user : users) {
5693                    int pkgUid = -1;
5694                    try {
5695                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5696                                user);
5697                    } catch (RemoteException e) {
5698                    }
5699                    if (pkgUid == -1) {
5700                        Slog.w(TAG, "Invalid packageName: " + packageName);
5701                        continue;
5702                    }
5703                    try {
5704                        pm.setPackageStoppedState(packageName, true, user);
5705                    } catch (RemoteException e) {
5706                    } catch (IllegalArgumentException e) {
5707                        Slog.w(TAG, "Failed trying to unstop package "
5708                                + packageName + ": " + e);
5709                    }
5710                    if (mUserController.isUserRunningLocked(user, 0)) {
5711                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5712                        finishForceStopPackageLocked(packageName, pkgUid);
5713                    }
5714                }
5715            }
5716        } finally {
5717            Binder.restoreCallingIdentity(callingId);
5718        }
5719    }
5720
5721    @Override
5722    public void addPackageDependency(String packageName) {
5723        synchronized (this) {
5724            int callingPid = Binder.getCallingPid();
5725            if (callingPid == Process.myPid()) {
5726                //  Yeah, um, no.
5727                return;
5728            }
5729            ProcessRecord proc;
5730            synchronized (mPidsSelfLocked) {
5731                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5732            }
5733            if (proc != null) {
5734                if (proc.pkgDeps == null) {
5735                    proc.pkgDeps = new ArraySet<String>(1);
5736                }
5737                proc.pkgDeps.add(packageName);
5738            }
5739        }
5740    }
5741
5742    /*
5743     * The pkg name and app id have to be specified.
5744     */
5745    @Override
5746    public void killApplication(String pkg, int appId, int userId, String reason) {
5747        if (pkg == null) {
5748            return;
5749        }
5750        // Make sure the uid is valid.
5751        if (appId < 0) {
5752            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5753            return;
5754        }
5755        int callerUid = Binder.getCallingUid();
5756        // Only the system server can kill an application
5757        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5758            // Post an aysnc message to kill the application
5759            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5760            msg.arg1 = appId;
5761            msg.arg2 = userId;
5762            Bundle bundle = new Bundle();
5763            bundle.putString("pkg", pkg);
5764            bundle.putString("reason", reason);
5765            msg.obj = bundle;
5766            mHandler.sendMessage(msg);
5767        } else {
5768            throw new SecurityException(callerUid + " cannot kill pkg: " +
5769                    pkg);
5770        }
5771    }
5772
5773    @Override
5774    public void closeSystemDialogs(String reason) {
5775        enforceNotIsolatedCaller("closeSystemDialogs");
5776
5777        final int pid = Binder.getCallingPid();
5778        final int uid = Binder.getCallingUid();
5779        final long origId = Binder.clearCallingIdentity();
5780        try {
5781            synchronized (this) {
5782                // Only allow this from foreground processes, so that background
5783                // applications can't abuse it to prevent system UI from being shown.
5784                if (uid >= Process.FIRST_APPLICATION_UID) {
5785                    ProcessRecord proc;
5786                    synchronized (mPidsSelfLocked) {
5787                        proc = mPidsSelfLocked.get(pid);
5788                    }
5789                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5790                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5791                                + " from background process " + proc);
5792                        return;
5793                    }
5794                }
5795                closeSystemDialogsLocked(reason);
5796            }
5797        } finally {
5798            Binder.restoreCallingIdentity(origId);
5799        }
5800    }
5801
5802    void closeSystemDialogsLocked(String reason) {
5803        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5804        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5805                | Intent.FLAG_RECEIVER_FOREGROUND);
5806        if (reason != null) {
5807            intent.putExtra("reason", reason);
5808        }
5809        mWindowManager.closeSystemDialogs(reason);
5810
5811        mStackSupervisor.closeSystemDialogsLocked();
5812
5813        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5814                AppOpsManager.OP_NONE, null, false, false,
5815                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5816    }
5817
5818    @Override
5819    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5820        enforceNotIsolatedCaller("getProcessMemoryInfo");
5821        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5822        for (int i=pids.length-1; i>=0; i--) {
5823            ProcessRecord proc;
5824            int oomAdj;
5825            synchronized (this) {
5826                synchronized (mPidsSelfLocked) {
5827                    proc = mPidsSelfLocked.get(pids[i]);
5828                    oomAdj = proc != null ? proc.setAdj : 0;
5829                }
5830            }
5831            infos[i] = new Debug.MemoryInfo();
5832            Debug.getMemoryInfo(pids[i], infos[i]);
5833            if (proc != null) {
5834                synchronized (this) {
5835                    if (proc.thread != null && proc.setAdj == oomAdj) {
5836                        // Record this for posterity if the process has been stable.
5837                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5838                                infos[i].getTotalUss(), false, proc.pkgList);
5839                    }
5840                }
5841            }
5842        }
5843        return infos;
5844    }
5845
5846    @Override
5847    public long[] getProcessPss(int[] pids) {
5848        enforceNotIsolatedCaller("getProcessPss");
5849        long[] pss = new long[pids.length];
5850        for (int i=pids.length-1; i>=0; i--) {
5851            ProcessRecord proc;
5852            int oomAdj;
5853            synchronized (this) {
5854                synchronized (mPidsSelfLocked) {
5855                    proc = mPidsSelfLocked.get(pids[i]);
5856                    oomAdj = proc != null ? proc.setAdj : 0;
5857                }
5858            }
5859            long[] tmpUss = new long[1];
5860            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5861            if (proc != null) {
5862                synchronized (this) {
5863                    if (proc.thread != null && proc.setAdj == oomAdj) {
5864                        // Record this for posterity if the process has been stable.
5865                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5866                    }
5867                }
5868            }
5869        }
5870        return pss;
5871    }
5872
5873    @Override
5874    public void killApplicationProcess(String processName, int uid) {
5875        if (processName == null) {
5876            return;
5877        }
5878
5879        int callerUid = Binder.getCallingUid();
5880        // Only the system server can kill an application
5881        if (callerUid == Process.SYSTEM_UID) {
5882            synchronized (this) {
5883                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5884                if (app != null && app.thread != null) {
5885                    try {
5886                        app.thread.scheduleSuicide();
5887                    } catch (RemoteException e) {
5888                        // If the other end already died, then our work here is done.
5889                    }
5890                } else {
5891                    Slog.w(TAG, "Process/uid not found attempting kill of "
5892                            + processName + " / " + uid);
5893                }
5894            }
5895        } else {
5896            throw new SecurityException(callerUid + " cannot kill app process: " +
5897                    processName);
5898        }
5899    }
5900
5901    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5902        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5903                false, true, false, false, UserHandle.getUserId(uid), reason);
5904    }
5905
5906    private void finishForceStopPackageLocked(final String packageName, int uid) {
5907        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5908                Uri.fromParts("package", packageName, null));
5909        if (!mProcessesReady) {
5910            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5911                    | Intent.FLAG_RECEIVER_FOREGROUND);
5912        }
5913        intent.putExtra(Intent.EXTRA_UID, uid);
5914        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5915        broadcastIntentLocked(null, null, intent,
5916                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5917                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5918    }
5919
5920
5921    private final boolean killPackageProcessesLocked(String packageName, int appId,
5922            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5923            boolean doit, boolean evenPersistent, String reason) {
5924        ArrayList<ProcessRecord> procs = new ArrayList<>();
5925
5926        // Remove all processes this package may have touched: all with the
5927        // same UID (except for the system or root user), and all whose name
5928        // matches the package name.
5929        final int NP = mProcessNames.getMap().size();
5930        for (int ip=0; ip<NP; ip++) {
5931            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5932            final int NA = apps.size();
5933            for (int ia=0; ia<NA; ia++) {
5934                ProcessRecord app = apps.valueAt(ia);
5935                if (app.persistent && !evenPersistent) {
5936                    // we don't kill persistent processes
5937                    continue;
5938                }
5939                if (app.removed) {
5940                    if (doit) {
5941                        procs.add(app);
5942                    }
5943                    continue;
5944                }
5945
5946                // Skip process if it doesn't meet our oom adj requirement.
5947                if (app.setAdj < minOomAdj) {
5948                    continue;
5949                }
5950
5951                // If no package is specified, we call all processes under the
5952                // give user id.
5953                if (packageName == null) {
5954                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5955                        continue;
5956                    }
5957                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5958                        continue;
5959                    }
5960                // Package has been specified, we want to hit all processes
5961                // that match it.  We need to qualify this by the processes
5962                // that are running under the specified app and user ID.
5963                } else {
5964                    final boolean isDep = app.pkgDeps != null
5965                            && app.pkgDeps.contains(packageName);
5966                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5967                        continue;
5968                    }
5969                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5970                        continue;
5971                    }
5972                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5973                        continue;
5974                    }
5975                }
5976
5977                // Process has passed all conditions, kill it!
5978                if (!doit) {
5979                    return true;
5980                }
5981                app.removed = true;
5982                procs.add(app);
5983            }
5984        }
5985
5986        int N = procs.size();
5987        for (int i=0; i<N; i++) {
5988            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5989        }
5990        updateOomAdjLocked();
5991        return N > 0;
5992    }
5993
5994    private void cleanupDisabledPackageComponentsLocked(
5995            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5996
5997        Set<String> disabledClasses = null;
5998        boolean packageDisabled = false;
5999        IPackageManager pm = AppGlobals.getPackageManager();
6000
6001        if (changedClasses == null) {
6002            // Nothing changed...
6003            return;
6004        }
6005
6006        // Determine enable/disable state of the package and its components.
6007        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6008        for (int i = changedClasses.length - 1; i >= 0; i--) {
6009            final String changedClass = changedClasses[i];
6010
6011            if (changedClass.equals(packageName)) {
6012                try {
6013                    // Entire package setting changed
6014                    enabled = pm.getApplicationEnabledSetting(packageName,
6015                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6016                } catch (Exception e) {
6017                    // No such package/component; probably racing with uninstall.  In any
6018                    // event it means we have nothing further to do here.
6019                    return;
6020                }
6021                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6022                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6023                if (packageDisabled) {
6024                    // Entire package is disabled.
6025                    // No need to continue to check component states.
6026                    disabledClasses = null;
6027                    break;
6028                }
6029            } else {
6030                try {
6031                    enabled = pm.getComponentEnabledSetting(
6032                            new ComponentName(packageName, changedClass),
6033                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6034                } catch (Exception e) {
6035                    // As above, probably racing with uninstall.
6036                    return;
6037                }
6038                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6039                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6040                    if (disabledClasses == null) {
6041                        disabledClasses = new ArraySet<>(changedClasses.length);
6042                    }
6043                    disabledClasses.add(changedClass);
6044                }
6045            }
6046        }
6047
6048        if (!packageDisabled && disabledClasses == null) {
6049            // Nothing to do here...
6050            return;
6051        }
6052
6053        // Clean-up disabled activities.
6054        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6055                packageName, disabledClasses, true, false, userId) && mBooted) {
6056            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6057            mStackSupervisor.scheduleIdleLocked();
6058        }
6059
6060        // Clean-up disabled tasks
6061        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6062
6063        // Clean-up disabled services.
6064        mServices.bringDownDisabledPackageServicesLocked(
6065                packageName, disabledClasses, userId, false, killProcess, true);
6066
6067        // Clean-up disabled providers.
6068        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6069        mProviderMap.collectPackageProvidersLocked(
6070                packageName, disabledClasses, true, false, userId, providers);
6071        for (int i = providers.size() - 1; i >= 0; i--) {
6072            removeDyingProviderLocked(null, providers.get(i), true);
6073        }
6074
6075        // Clean-up disabled broadcast receivers.
6076        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6077            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6078                    packageName, disabledClasses, userId, true);
6079        }
6080
6081    }
6082
6083    final boolean clearBroadcastQueueForUserLocked(int userId) {
6084        boolean didSomething = false;
6085        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6086            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6087                    null, null, userId, true);
6088        }
6089        return didSomething;
6090    }
6091
6092    final boolean forceStopPackageLocked(String packageName, int appId,
6093            boolean callerWillRestart, boolean purgeCache, boolean doit,
6094            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6095        int i;
6096
6097        if (userId == UserHandle.USER_ALL && packageName == null) {
6098            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6099        }
6100
6101        if (appId < 0 && packageName != null) {
6102            try {
6103                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6104                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6105            } catch (RemoteException e) {
6106            }
6107        }
6108
6109        if (doit) {
6110            if (packageName != null) {
6111                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6112                        + " user=" + userId + ": " + reason);
6113            } else {
6114                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6115            }
6116
6117            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6118        }
6119
6120        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6121                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6122                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6123
6124        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6125
6126        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6127                packageName, null, doit, evenPersistent, userId)) {
6128            if (!doit) {
6129                return true;
6130            }
6131            didSomething = true;
6132        }
6133
6134        if (mServices.bringDownDisabledPackageServicesLocked(
6135                packageName, null, userId, evenPersistent, true, doit)) {
6136            if (!doit) {
6137                return true;
6138            }
6139            didSomething = true;
6140        }
6141
6142        if (packageName == null) {
6143            // Remove all sticky broadcasts from this user.
6144            mStickyBroadcasts.remove(userId);
6145        }
6146
6147        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6148        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6149                userId, providers)) {
6150            if (!doit) {
6151                return true;
6152            }
6153            didSomething = true;
6154        }
6155        for (i = providers.size() - 1; i >= 0; i--) {
6156            removeDyingProviderLocked(null, providers.get(i), true);
6157        }
6158
6159        // Remove transient permissions granted from/to this package/user
6160        removeUriPermissionsForPackageLocked(packageName, userId, false);
6161
6162        if (doit) {
6163            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6164                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6165                        packageName, null, userId, doit);
6166            }
6167        }
6168
6169        if (packageName == null || uninstalling) {
6170            // Remove pending intents.  For now we only do this when force
6171            // stopping users, because we have some problems when doing this
6172            // for packages -- app widgets are not currently cleaned up for
6173            // such packages, so they can be left with bad pending intents.
6174            if (mIntentSenderRecords.size() > 0) {
6175                Iterator<WeakReference<PendingIntentRecord>> it
6176                        = mIntentSenderRecords.values().iterator();
6177                while (it.hasNext()) {
6178                    WeakReference<PendingIntentRecord> wpir = it.next();
6179                    if (wpir == null) {
6180                        it.remove();
6181                        continue;
6182                    }
6183                    PendingIntentRecord pir = wpir.get();
6184                    if (pir == null) {
6185                        it.remove();
6186                        continue;
6187                    }
6188                    if (packageName == null) {
6189                        // Stopping user, remove all objects for the user.
6190                        if (pir.key.userId != userId) {
6191                            // Not the same user, skip it.
6192                            continue;
6193                        }
6194                    } else {
6195                        if (UserHandle.getAppId(pir.uid) != appId) {
6196                            // Different app id, skip it.
6197                            continue;
6198                        }
6199                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6200                            // Different user, skip it.
6201                            continue;
6202                        }
6203                        if (!pir.key.packageName.equals(packageName)) {
6204                            // Different package, skip it.
6205                            continue;
6206                        }
6207                    }
6208                    if (!doit) {
6209                        return true;
6210                    }
6211                    didSomething = true;
6212                    it.remove();
6213                    pir.canceled = true;
6214                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6215                        pir.key.activity.pendingResults.remove(pir.ref);
6216                    }
6217                }
6218            }
6219        }
6220
6221        if (doit) {
6222            if (purgeCache && packageName != null) {
6223                AttributeCache ac = AttributeCache.instance();
6224                if (ac != null) {
6225                    ac.removePackage(packageName);
6226                }
6227            }
6228            if (mBooted) {
6229                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6230                mStackSupervisor.scheduleIdleLocked();
6231            }
6232        }
6233
6234        return didSomething;
6235    }
6236
6237    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6238        return removeProcessNameLocked(name, uid, null);
6239    }
6240
6241    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6242            final ProcessRecord expecting) {
6243        ProcessRecord old = mProcessNames.get(name, uid);
6244        // Only actually remove when the currently recorded value matches the
6245        // record that we expected; if it doesn't match then we raced with a
6246        // newly created process and we don't want to destroy the new one.
6247        if ((expecting == null) || (old == expecting)) {
6248            mProcessNames.remove(name, uid);
6249        }
6250        if (old != null && old.uidRecord != null) {
6251            old.uidRecord.numProcs--;
6252            if (old.uidRecord.numProcs == 0) {
6253                // No more processes using this uid, tell clients it is gone.
6254                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6255                        "No more processes in " + old.uidRecord);
6256                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6257                mActiveUids.remove(uid);
6258                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6259            }
6260            old.uidRecord = null;
6261        }
6262        mIsolatedProcesses.remove(uid);
6263        return old;
6264    }
6265
6266    private final void addProcessNameLocked(ProcessRecord proc) {
6267        // We shouldn't already have a process under this name, but just in case we
6268        // need to clean up whatever may be there now.
6269        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6270        if (old == proc && proc.persistent) {
6271            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6272            Slog.w(TAG, "Re-adding persistent process " + proc);
6273        } else if (old != null) {
6274            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6275        }
6276        UidRecord uidRec = mActiveUids.get(proc.uid);
6277        if (uidRec == null) {
6278            uidRec = new UidRecord(proc.uid);
6279            // This is the first appearance of the uid, report it now!
6280            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6281                    "Creating new process uid: " + uidRec);
6282            mActiveUids.put(proc.uid, uidRec);
6283            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6284            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6285        }
6286        proc.uidRecord = uidRec;
6287
6288        // Reset render thread tid if it was already set, so new process can set it again.
6289        proc.renderThreadTid = 0;
6290        uidRec.numProcs++;
6291        mProcessNames.put(proc.processName, proc.uid, proc);
6292        if (proc.isolated) {
6293            mIsolatedProcesses.put(proc.uid, proc);
6294        }
6295    }
6296
6297    boolean removeProcessLocked(ProcessRecord app,
6298            boolean callerWillRestart, boolean allowRestart, String reason) {
6299        final String name = app.processName;
6300        final int uid = app.uid;
6301        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6302            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6303
6304        ProcessRecord old = mProcessNames.get(name, uid);
6305        if (old != app) {
6306            // This process is no longer active, so nothing to do.
6307            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6308            return false;
6309        }
6310        removeProcessNameLocked(name, uid);
6311        if (mHeavyWeightProcess == app) {
6312            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6313                    mHeavyWeightProcess.userId, 0));
6314            mHeavyWeightProcess = null;
6315        }
6316        boolean needRestart = false;
6317        if (app.pid > 0 && app.pid != MY_PID) {
6318            int pid = app.pid;
6319            synchronized (mPidsSelfLocked) {
6320                mPidsSelfLocked.remove(pid);
6321                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6322            }
6323            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6324            if (app.isolated) {
6325                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6326            }
6327            boolean willRestart = false;
6328            if (app.persistent && !app.isolated) {
6329                if (!callerWillRestart) {
6330                    willRestart = true;
6331                } else {
6332                    needRestart = true;
6333                }
6334            }
6335            app.kill(reason, true);
6336            handleAppDiedLocked(app, willRestart, allowRestart);
6337            if (willRestart) {
6338                removeLruProcessLocked(app);
6339                addAppLocked(app.info, false, null /* ABI override */);
6340            }
6341        } else {
6342            mRemovedProcesses.add(app);
6343        }
6344
6345        return needRestart;
6346    }
6347
6348    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6349        cleanupAppInLaunchingProvidersLocked(app, true);
6350        removeProcessLocked(app, false, true, "timeout publishing content providers");
6351    }
6352
6353    private final void processStartTimedOutLocked(ProcessRecord app) {
6354        final int pid = app.pid;
6355        boolean gone = false;
6356        synchronized (mPidsSelfLocked) {
6357            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6358            if (knownApp != null && knownApp.thread == null) {
6359                mPidsSelfLocked.remove(pid);
6360                gone = true;
6361            }
6362        }
6363
6364        if (gone) {
6365            Slog.w(TAG, "Process " + app + " failed to attach");
6366            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6367                    pid, app.uid, app.processName);
6368            removeProcessNameLocked(app.processName, app.uid);
6369            if (mHeavyWeightProcess == app) {
6370                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6371                        mHeavyWeightProcess.userId, 0));
6372                mHeavyWeightProcess = null;
6373            }
6374            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6375            if (app.isolated) {
6376                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6377            }
6378            // Take care of any launching providers waiting for this process.
6379            cleanupAppInLaunchingProvidersLocked(app, true);
6380            // Take care of any services that are waiting for the process.
6381            mServices.processStartTimedOutLocked(app);
6382            app.kill("start timeout", true);
6383            removeLruProcessLocked(app);
6384            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6385                Slog.w(TAG, "Unattached app died before backup, skipping");
6386                mHandler.post(new Runnable() {
6387                @Override
6388                    public void run(){
6389                        try {
6390                            IBackupManager bm = IBackupManager.Stub.asInterface(
6391                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6392                            bm.agentDisconnected(app.info.packageName);
6393                        } catch (RemoteException e) {
6394                            // Can't happen; the backup manager is local
6395                        }
6396                    }
6397                });
6398            }
6399            if (isPendingBroadcastProcessLocked(pid)) {
6400                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6401                skipPendingBroadcastLocked(pid);
6402            }
6403        } else {
6404            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6405        }
6406    }
6407
6408    private final boolean attachApplicationLocked(IApplicationThread thread,
6409            int pid) {
6410
6411        // Find the application record that is being attached...  either via
6412        // the pid if we are running in multiple processes, or just pull the
6413        // next app record if we are emulating process with anonymous threads.
6414        ProcessRecord app;
6415        if (pid != MY_PID && pid >= 0) {
6416            synchronized (mPidsSelfLocked) {
6417                app = mPidsSelfLocked.get(pid);
6418            }
6419        } else {
6420            app = null;
6421        }
6422
6423        if (app == null) {
6424            Slog.w(TAG, "No pending application record for pid " + pid
6425                    + " (IApplicationThread " + thread + "); dropping process");
6426            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6427            if (pid > 0 && pid != MY_PID) {
6428                Process.killProcessQuiet(pid);
6429                //TODO: killProcessGroup(app.info.uid, pid);
6430            } else {
6431                try {
6432                    thread.scheduleExit();
6433                } catch (Exception e) {
6434                    // Ignore exceptions.
6435                }
6436            }
6437            return false;
6438        }
6439
6440        // If this application record is still attached to a previous
6441        // process, clean it up now.
6442        if (app.thread != null) {
6443            handleAppDiedLocked(app, true, true);
6444        }
6445
6446        // Tell the process all about itself.
6447
6448        if (DEBUG_ALL) Slog.v(
6449                TAG, "Binding process pid " + pid + " to record " + app);
6450
6451        final String processName = app.processName;
6452        try {
6453            AppDeathRecipient adr = new AppDeathRecipient(
6454                    app, pid, thread);
6455            thread.asBinder().linkToDeath(adr, 0);
6456            app.deathRecipient = adr;
6457        } catch (RemoteException e) {
6458            app.resetPackageList(mProcessStats);
6459            startProcessLocked(app, "link fail", processName);
6460            return false;
6461        }
6462
6463        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6464
6465        app.makeActive(thread, mProcessStats);
6466        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6467        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6468        app.forcingToForeground = null;
6469        updateProcessForegroundLocked(app, false, false);
6470        app.hasShownUi = false;
6471        app.debugging = false;
6472        app.cached = false;
6473        app.killedByAm = false;
6474        app.killed = false;
6475
6476
6477        // We carefully use the same state that PackageManager uses for
6478        // filtering, since we use this flag to decide if we need to install
6479        // providers when user is unlocked later
6480        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6481
6482        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6483
6484        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6485        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6486
6487        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6488            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6489            msg.obj = app;
6490            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6491        }
6492
6493        if (!normalMode) {
6494            Slog.i(TAG, "Launching preboot mode app: " + app);
6495        }
6496
6497        if (DEBUG_ALL) Slog.v(
6498            TAG, "New app record " + app
6499            + " thread=" + thread.asBinder() + " pid=" + pid);
6500        try {
6501            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6502            if (mDebugApp != null && mDebugApp.equals(processName)) {
6503                testMode = mWaitForDebugger
6504                    ? ApplicationThreadConstants.DEBUG_WAIT
6505                    : ApplicationThreadConstants.DEBUG_ON;
6506                app.debugging = true;
6507                if (mDebugTransient) {
6508                    mDebugApp = mOrigDebugApp;
6509                    mWaitForDebugger = mOrigWaitForDebugger;
6510                }
6511            }
6512            String profileFile = app.instrumentationProfileFile;
6513            ParcelFileDescriptor profileFd = null;
6514            int samplingInterval = 0;
6515            boolean profileAutoStop = false;
6516            if (mProfileApp != null && mProfileApp.equals(processName)) {
6517                mProfileProc = app;
6518                profileFile = mProfileFile;
6519                profileFd = mProfileFd;
6520                samplingInterval = mSamplingInterval;
6521                profileAutoStop = mAutoStopProfiler;
6522            }
6523            boolean enableTrackAllocation = false;
6524            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6525                enableTrackAllocation = true;
6526                mTrackAllocationApp = null;
6527            }
6528
6529            // If the app is being launched for restore or full backup, set it up specially
6530            boolean isRestrictedBackupMode = false;
6531            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6532                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6533                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6534                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6535                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6536            }
6537
6538            if (app.instrumentationClass != null) {
6539                notifyPackageUse(app.instrumentationClass.getPackageName(),
6540                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6541            }
6542            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6543                    + processName + " with config " + getGlobalConfiguration());
6544            ApplicationInfo appInfo = app.instrumentationInfo != null
6545                    ? app.instrumentationInfo : app.info;
6546            app.compat = compatibilityInfoForPackageLocked(appInfo);
6547            if (profileFd != null) {
6548                profileFd = profileFd.dup();
6549            }
6550            ProfilerInfo profilerInfo = profileFile == null ? null
6551                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6552
6553            // We deprecated Build.SERIAL and only apps that target pre NMR1
6554            // SDK can see it. Since access to the serial is now behind a
6555            // permission we push down the value.
6556            String buildSerial = Build.UNKNOWN;
6557            // TODO: SHTOPSHIP Uncomment the check when clients migrate
6558//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6559                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6560                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6561                        .getSerial();
6562//            }
6563
6564            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6565                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6566                    app.instrumentationUiAutomationConnection, testMode,
6567                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6568                    isRestrictedBackupMode || !normalMode, app.persistent,
6569                    new Configuration(getGlobalConfiguration()), app.compat,
6570                    getCommonServicesLocked(app.isolated),
6571                    mCoreSettingsObserver.getCoreSettingsLocked(),
6572                    buildSerial);
6573
6574            updateLruProcessLocked(app, false, null);
6575            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6576        } catch (Exception e) {
6577            // todo: Yikes!  What should we do?  For now we will try to
6578            // start another process, but that could easily get us in
6579            // an infinite loop of restarting processes...
6580            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6581
6582            app.resetPackageList(mProcessStats);
6583            app.unlinkDeathRecipient();
6584            startProcessLocked(app, "bind fail", processName);
6585            return false;
6586        }
6587
6588        // Remove this record from the list of starting applications.
6589        mPersistentStartingProcesses.remove(app);
6590        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6591                "Attach application locked removing on hold: " + app);
6592        mProcessesOnHold.remove(app);
6593
6594        boolean badApp = false;
6595        boolean didSomething = false;
6596
6597        // See if the top visible activity is waiting to run in this process...
6598        if (normalMode) {
6599            try {
6600                if (mStackSupervisor.attachApplicationLocked(app)) {
6601                    didSomething = true;
6602                }
6603            } catch (Exception e) {
6604                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6605                badApp = true;
6606            }
6607        }
6608
6609        // Find any services that should be running in this process...
6610        if (!badApp) {
6611            try {
6612                didSomething |= mServices.attachApplicationLocked(app, processName);
6613            } catch (Exception e) {
6614                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6615                badApp = true;
6616            }
6617        }
6618
6619        // Check if a next-broadcast receiver is in this process...
6620        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6621            try {
6622                didSomething |= sendPendingBroadcastsLocked(app);
6623            } catch (Exception e) {
6624                // If the app died trying to launch the receiver we declare it 'bad'
6625                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6626                badApp = true;
6627            }
6628        }
6629
6630        // Check whether the next backup agent is in this process...
6631        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6632            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6633                    "New app is backup target, launching agent for " + app);
6634            notifyPackageUse(mBackupTarget.appInfo.packageName,
6635                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6636            try {
6637                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6638                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6639                        mBackupTarget.backupMode);
6640            } catch (Exception e) {
6641                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6642                badApp = true;
6643            }
6644        }
6645
6646        if (badApp) {
6647            app.kill("error during init", true);
6648            handleAppDiedLocked(app, false, true);
6649            return false;
6650        }
6651
6652        if (!didSomething) {
6653            updateOomAdjLocked();
6654        }
6655
6656        return true;
6657    }
6658
6659    @Override
6660    public final void attachApplication(IApplicationThread thread) {
6661        synchronized (this) {
6662            int callingPid = Binder.getCallingPid();
6663            final long origId = Binder.clearCallingIdentity();
6664            attachApplicationLocked(thread, callingPid);
6665            Binder.restoreCallingIdentity(origId);
6666        }
6667    }
6668
6669    @Override
6670    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6671        final long origId = Binder.clearCallingIdentity();
6672        synchronized (this) {
6673            ActivityStack stack = ActivityRecord.getStackLocked(token);
6674            if (stack != null) {
6675                ActivityRecord r =
6676                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6677                if (stopProfiling) {
6678                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6679                        try {
6680                            mProfileFd.close();
6681                        } catch (IOException e) {
6682                        }
6683                        clearProfilerLocked();
6684                    }
6685                }
6686            }
6687        }
6688        Binder.restoreCallingIdentity(origId);
6689    }
6690
6691    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6692        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6693                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6694    }
6695
6696    void enableScreenAfterBoot() {
6697        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6698                SystemClock.uptimeMillis());
6699        mWindowManager.enableScreenAfterBoot();
6700
6701        synchronized (this) {
6702            updateEventDispatchingLocked();
6703        }
6704    }
6705
6706    @Override
6707    public void showBootMessage(final CharSequence msg, final boolean always) {
6708        if (Binder.getCallingUid() != Process.myUid()) {
6709            throw new SecurityException();
6710        }
6711        mWindowManager.showBootMessage(msg, always);
6712    }
6713
6714    @Override
6715    public void keyguardGoingAway(int flags) {
6716        enforceNotIsolatedCaller("keyguardGoingAway");
6717        final long token = Binder.clearCallingIdentity();
6718        try {
6719            synchronized (this) {
6720                mKeyguardController.keyguardGoingAway(flags);
6721            }
6722        } finally {
6723            Binder.restoreCallingIdentity(token);
6724        }
6725    }
6726
6727    /**
6728     * @return whther the keyguard is currently locked.
6729     */
6730    boolean isKeyguardLocked() {
6731        return mKeyguardController.isKeyguardLocked();
6732    }
6733
6734    final void finishBooting() {
6735        synchronized (this) {
6736            if (!mBootAnimationComplete) {
6737                mCallFinishBooting = true;
6738                return;
6739            }
6740            mCallFinishBooting = false;
6741        }
6742
6743        ArraySet<String> completedIsas = new ArraySet<String>();
6744        for (String abi : Build.SUPPORTED_ABIS) {
6745            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6746            final String instructionSet = VMRuntime.getInstructionSet(abi);
6747            if (!completedIsas.contains(instructionSet)) {
6748                try {
6749                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6750                } catch (InstallerException e) {
6751                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6752                            e.getMessage() +")");
6753                }
6754                completedIsas.add(instructionSet);
6755            }
6756        }
6757
6758        IntentFilter pkgFilter = new IntentFilter();
6759        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6760        pkgFilter.addDataScheme("package");
6761        mContext.registerReceiver(new BroadcastReceiver() {
6762            @Override
6763            public void onReceive(Context context, Intent intent) {
6764                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6765                if (pkgs != null) {
6766                    for (String pkg : pkgs) {
6767                        synchronized (ActivityManagerService.this) {
6768                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6769                                    0, "query restart")) {
6770                                setResultCode(Activity.RESULT_OK);
6771                                return;
6772                            }
6773                        }
6774                    }
6775                }
6776            }
6777        }, pkgFilter);
6778
6779        IntentFilter dumpheapFilter = new IntentFilter();
6780        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6781        mContext.registerReceiver(new BroadcastReceiver() {
6782            @Override
6783            public void onReceive(Context context, Intent intent) {
6784                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6785                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6786                } else {
6787                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6788                }
6789            }
6790        }, dumpheapFilter);
6791
6792        // Let system services know.
6793        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6794
6795        synchronized (this) {
6796            // Ensure that any processes we had put on hold are now started
6797            // up.
6798            final int NP = mProcessesOnHold.size();
6799            if (NP > 0) {
6800                ArrayList<ProcessRecord> procs =
6801                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6802                for (int ip=0; ip<NP; ip++) {
6803                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6804                            + procs.get(ip));
6805                    startProcessLocked(procs.get(ip), "on-hold", null);
6806                }
6807            }
6808
6809            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6810                // Start looking for apps that are abusing wake locks.
6811                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6812                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6813                // Tell anyone interested that we are done booting!
6814                SystemProperties.set("sys.boot_completed", "1");
6815
6816                // And trigger dev.bootcomplete if we are not showing encryption progress
6817                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6818                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6819                    SystemProperties.set("dev.bootcomplete", "1");
6820                }
6821                mUserController.sendBootCompletedLocked(
6822                        new IIntentReceiver.Stub() {
6823                            @Override
6824                            public void performReceive(Intent intent, int resultCode,
6825                                    String data, Bundle extras, boolean ordered,
6826                                    boolean sticky, int sendingUser) {
6827                                synchronized (ActivityManagerService.this) {
6828                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6829                                            true, false);
6830                                }
6831                            }
6832                        });
6833                scheduleStartProfilesLocked();
6834            }
6835        }
6836    }
6837
6838    @Override
6839    public void bootAnimationComplete() {
6840        final boolean callFinishBooting;
6841        synchronized (this) {
6842            callFinishBooting = mCallFinishBooting;
6843            mBootAnimationComplete = true;
6844        }
6845        if (callFinishBooting) {
6846            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6847            finishBooting();
6848            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6849        }
6850    }
6851
6852    final void ensureBootCompleted() {
6853        boolean booting;
6854        boolean enableScreen;
6855        synchronized (this) {
6856            booting = mBooting;
6857            mBooting = false;
6858            enableScreen = !mBooted;
6859            mBooted = true;
6860        }
6861
6862        if (booting) {
6863            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6864            finishBooting();
6865            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6866        }
6867
6868        if (enableScreen) {
6869            enableScreenAfterBoot();
6870        }
6871    }
6872
6873    @Override
6874    public final void activityResumed(IBinder token) {
6875        final long origId = Binder.clearCallingIdentity();
6876        synchronized(this) {
6877            ActivityRecord.activityResumedLocked(token);
6878            mWindowManager.notifyAppResumedFinished(token);
6879        }
6880        Binder.restoreCallingIdentity(origId);
6881    }
6882
6883    @Override
6884    public final void activityPaused(IBinder token) {
6885        final long origId = Binder.clearCallingIdentity();
6886        synchronized(this) {
6887            ActivityStack stack = ActivityRecord.getStackLocked(token);
6888            if (stack != null) {
6889                stack.activityPausedLocked(token, false);
6890            }
6891        }
6892        Binder.restoreCallingIdentity(origId);
6893    }
6894
6895    @Override
6896    public final void activityStopped(IBinder token, Bundle icicle,
6897            PersistableBundle persistentState, CharSequence description) {
6898        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6899
6900        // Refuse possible leaked file descriptors
6901        if (icicle != null && icicle.hasFileDescriptors()) {
6902            throw new IllegalArgumentException("File descriptors passed in Bundle");
6903        }
6904
6905        final long origId = Binder.clearCallingIdentity();
6906
6907        synchronized (this) {
6908            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6909            if (r != null) {
6910                r.activityStoppedLocked(icicle, persistentState, description);
6911            }
6912        }
6913
6914        trimApplications();
6915
6916        Binder.restoreCallingIdentity(origId);
6917    }
6918
6919    @Override
6920    public final void activityDestroyed(IBinder token) {
6921        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6922        synchronized (this) {
6923            ActivityStack stack = ActivityRecord.getStackLocked(token);
6924            if (stack != null) {
6925                stack.activityDestroyedLocked(token, "activityDestroyed");
6926            }
6927        }
6928    }
6929
6930    @Override
6931    public final void activityRelaunched(IBinder token) {
6932        final long origId = Binder.clearCallingIdentity();
6933        synchronized (this) {
6934            mStackSupervisor.activityRelaunchedLocked(token);
6935        }
6936        Binder.restoreCallingIdentity(origId);
6937    }
6938
6939    @Override
6940    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6941            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6942        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6943                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6944        synchronized (this) {
6945            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6946            if (record == null) {
6947                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6948                        + "found for: " + token);
6949            }
6950            record.setSizeConfigurations(horizontalSizeConfiguration,
6951                    verticalSizeConfigurations, smallestSizeConfigurations);
6952        }
6953    }
6954
6955    @Override
6956    public final void backgroundResourcesReleased(IBinder token) {
6957        final long origId = Binder.clearCallingIdentity();
6958        try {
6959            synchronized (this) {
6960                ActivityStack stack = ActivityRecord.getStackLocked(token);
6961                if (stack != null) {
6962                    stack.backgroundResourcesReleased();
6963                }
6964            }
6965        } finally {
6966            Binder.restoreCallingIdentity(origId);
6967        }
6968    }
6969
6970    @Override
6971    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6972        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6973    }
6974
6975    @Override
6976    public final void notifyEnterAnimationComplete(IBinder token) {
6977        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6978    }
6979
6980    @Override
6981    public String getCallingPackage(IBinder token) {
6982        synchronized (this) {
6983            ActivityRecord r = getCallingRecordLocked(token);
6984            return r != null ? r.info.packageName : null;
6985        }
6986    }
6987
6988    @Override
6989    public ComponentName getCallingActivity(IBinder token) {
6990        synchronized (this) {
6991            ActivityRecord r = getCallingRecordLocked(token);
6992            return r != null ? r.intent.getComponent() : null;
6993        }
6994    }
6995
6996    private ActivityRecord getCallingRecordLocked(IBinder token) {
6997        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6998        if (r == null) {
6999            return null;
7000        }
7001        return r.resultTo;
7002    }
7003
7004    @Override
7005    public ComponentName getActivityClassForToken(IBinder token) {
7006        synchronized(this) {
7007            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7008            if (r == null) {
7009                return null;
7010            }
7011            return r.intent.getComponent();
7012        }
7013    }
7014
7015    @Override
7016    public String getPackageForToken(IBinder token) {
7017        synchronized(this) {
7018            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7019            if (r == null) {
7020                return null;
7021            }
7022            return r.packageName;
7023        }
7024    }
7025
7026    @Override
7027    public boolean isRootVoiceInteraction(IBinder token) {
7028        synchronized(this) {
7029            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7030            if (r == null) {
7031                return false;
7032            }
7033            return r.rootVoiceInteraction;
7034        }
7035    }
7036
7037    @Override
7038    public IIntentSender getIntentSender(int type,
7039            String packageName, IBinder token, String resultWho,
7040            int requestCode, Intent[] intents, String[] resolvedTypes,
7041            int flags, Bundle bOptions, int userId) {
7042        enforceNotIsolatedCaller("getIntentSender");
7043        // Refuse possible leaked file descriptors
7044        if (intents != null) {
7045            if (intents.length < 1) {
7046                throw new IllegalArgumentException("Intents array length must be >= 1");
7047            }
7048            for (int i=0; i<intents.length; i++) {
7049                Intent intent = intents[i];
7050                if (intent != null) {
7051                    if (intent.hasFileDescriptors()) {
7052                        throw new IllegalArgumentException("File descriptors passed in Intent");
7053                    }
7054                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7055                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7056                        throw new IllegalArgumentException(
7057                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7058                    }
7059                    intents[i] = new Intent(intent);
7060                }
7061            }
7062            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7063                throw new IllegalArgumentException(
7064                        "Intent array length does not match resolvedTypes length");
7065            }
7066        }
7067        if (bOptions != null) {
7068            if (bOptions.hasFileDescriptors()) {
7069                throw new IllegalArgumentException("File descriptors passed in options");
7070            }
7071        }
7072
7073        synchronized(this) {
7074            int callingUid = Binder.getCallingUid();
7075            int origUserId = userId;
7076            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7077                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7078                    ALLOW_NON_FULL, "getIntentSender", null);
7079            if (origUserId == UserHandle.USER_CURRENT) {
7080                // We don't want to evaluate this until the pending intent is
7081                // actually executed.  However, we do want to always do the
7082                // security checking for it above.
7083                userId = UserHandle.USER_CURRENT;
7084            }
7085            try {
7086                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7087                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7088                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7089                    if (!UserHandle.isSameApp(callingUid, uid)) {
7090                        String msg = "Permission Denial: getIntentSender() from pid="
7091                            + Binder.getCallingPid()
7092                            + ", uid=" + Binder.getCallingUid()
7093                            + ", (need uid=" + uid + ")"
7094                            + " is not allowed to send as package " + packageName;
7095                        Slog.w(TAG, msg);
7096                        throw new SecurityException(msg);
7097                    }
7098                }
7099
7100                return getIntentSenderLocked(type, packageName, callingUid, userId,
7101                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7102
7103            } catch (RemoteException e) {
7104                throw new SecurityException(e);
7105            }
7106        }
7107    }
7108
7109    IIntentSender getIntentSenderLocked(int type, String packageName,
7110            int callingUid, int userId, IBinder token, String resultWho,
7111            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7112            Bundle bOptions) {
7113        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7114        ActivityRecord activity = null;
7115        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7116            activity = ActivityRecord.isInStackLocked(token);
7117            if (activity == null) {
7118                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7119                return null;
7120            }
7121            if (activity.finishing) {
7122                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7123                return null;
7124            }
7125        }
7126
7127        // We're going to be splicing together extras before sending, so we're
7128        // okay poking into any contained extras.
7129        if (intents != null) {
7130            for (int i = 0; i < intents.length; i++) {
7131                intents[i].setDefusable(true);
7132            }
7133        }
7134        Bundle.setDefusable(bOptions, true);
7135
7136        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7137        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7138        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7139        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7140                |PendingIntent.FLAG_UPDATE_CURRENT);
7141
7142        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7143                type, packageName, activity, resultWho,
7144                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7145        WeakReference<PendingIntentRecord> ref;
7146        ref = mIntentSenderRecords.get(key);
7147        PendingIntentRecord rec = ref != null ? ref.get() : null;
7148        if (rec != null) {
7149            if (!cancelCurrent) {
7150                if (updateCurrent) {
7151                    if (rec.key.requestIntent != null) {
7152                        rec.key.requestIntent.replaceExtras(intents != null ?
7153                                intents[intents.length - 1] : null);
7154                    }
7155                    if (intents != null) {
7156                        intents[intents.length-1] = rec.key.requestIntent;
7157                        rec.key.allIntents = intents;
7158                        rec.key.allResolvedTypes = resolvedTypes;
7159                    } else {
7160                        rec.key.allIntents = null;
7161                        rec.key.allResolvedTypes = null;
7162                    }
7163                }
7164                return rec;
7165            }
7166            rec.canceled = true;
7167            mIntentSenderRecords.remove(key);
7168        }
7169        if (noCreate) {
7170            return rec;
7171        }
7172        rec = new PendingIntentRecord(this, key, callingUid);
7173        mIntentSenderRecords.put(key, rec.ref);
7174        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7175            if (activity.pendingResults == null) {
7176                activity.pendingResults
7177                        = new HashSet<WeakReference<PendingIntentRecord>>();
7178            }
7179            activity.pendingResults.add(rec.ref);
7180        }
7181        return rec;
7182    }
7183
7184    @Override
7185    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7186            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7187        if (target instanceof PendingIntentRecord) {
7188            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7189                    finishedReceiver, requiredPermission, options);
7190        } else {
7191            if (intent == null) {
7192                // Weird case: someone has given us their own custom IIntentSender, and now
7193                // they have someone else trying to send to it but of course this isn't
7194                // really a PendingIntent, so there is no base Intent, and the caller isn't
7195                // supplying an Intent... but we never want to dispatch a null Intent to
7196                // a receiver, so um...  let's make something up.
7197                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7198                intent = new Intent(Intent.ACTION_MAIN);
7199            }
7200            try {
7201                target.send(code, intent, resolvedType, null, requiredPermission, options);
7202            } catch (RemoteException e) {
7203            }
7204            // Platform code can rely on getting a result back when the send is done, but if
7205            // this intent sender is from outside of the system we can't rely on it doing that.
7206            // So instead we don't give it the result receiver, and instead just directly
7207            // report the finish immediately.
7208            if (finishedReceiver != null) {
7209                try {
7210                    finishedReceiver.performReceive(intent, 0,
7211                            null, null, false, false, UserHandle.getCallingUserId());
7212                } catch (RemoteException e) {
7213                }
7214            }
7215            return 0;
7216        }
7217    }
7218
7219    /**
7220     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7221     *
7222     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7223     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7224     */
7225    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7226        if (DEBUG_WHITELISTS) {
7227            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7228                    + targetUid + ", " + duration + ")");
7229        }
7230        synchronized (mPidsSelfLocked) {
7231            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7232            if (pr == null) {
7233                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7234                return;
7235            }
7236            if (!pr.whitelistManager) {
7237                if (DEBUG_WHITELISTS) {
7238                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7239                            + callerPid + " is not allowed");
7240                }
7241                return;
7242            }
7243        }
7244
7245        final long token = Binder.clearCallingIdentity();
7246        try {
7247            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7248                    true, "pe from uid:" + callerUid);
7249        } finally {
7250            Binder.restoreCallingIdentity(token);
7251        }
7252    }
7253
7254    @Override
7255    public void cancelIntentSender(IIntentSender sender) {
7256        if (!(sender instanceof PendingIntentRecord)) {
7257            return;
7258        }
7259        synchronized(this) {
7260            PendingIntentRecord rec = (PendingIntentRecord)sender;
7261            try {
7262                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7263                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7264                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7265                    String msg = "Permission Denial: cancelIntentSender() from pid="
7266                        + Binder.getCallingPid()
7267                        + ", uid=" + Binder.getCallingUid()
7268                        + " is not allowed to cancel packges "
7269                        + rec.key.packageName;
7270                    Slog.w(TAG, msg);
7271                    throw new SecurityException(msg);
7272                }
7273            } catch (RemoteException e) {
7274                throw new SecurityException(e);
7275            }
7276            cancelIntentSenderLocked(rec, true);
7277        }
7278    }
7279
7280    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7281        rec.canceled = true;
7282        mIntentSenderRecords.remove(rec.key);
7283        if (cleanActivity && rec.key.activity != null) {
7284            rec.key.activity.pendingResults.remove(rec.ref);
7285        }
7286    }
7287
7288    @Override
7289    public String getPackageForIntentSender(IIntentSender pendingResult) {
7290        if (!(pendingResult instanceof PendingIntentRecord)) {
7291            return null;
7292        }
7293        try {
7294            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7295            return res.key.packageName;
7296        } catch (ClassCastException e) {
7297        }
7298        return null;
7299    }
7300
7301    @Override
7302    public int getUidForIntentSender(IIntentSender sender) {
7303        if (sender instanceof PendingIntentRecord) {
7304            try {
7305                PendingIntentRecord res = (PendingIntentRecord)sender;
7306                return res.uid;
7307            } catch (ClassCastException e) {
7308            }
7309        }
7310        return -1;
7311    }
7312
7313    @Override
7314    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7315        if (!(pendingResult instanceof PendingIntentRecord)) {
7316            return false;
7317        }
7318        try {
7319            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7320            if (res.key.allIntents == null) {
7321                return false;
7322            }
7323            for (int i=0; i<res.key.allIntents.length; i++) {
7324                Intent intent = res.key.allIntents[i];
7325                if (intent.getPackage() != null && intent.getComponent() != null) {
7326                    return false;
7327                }
7328            }
7329            return true;
7330        } catch (ClassCastException e) {
7331        }
7332        return false;
7333    }
7334
7335    @Override
7336    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7337        if (!(pendingResult instanceof PendingIntentRecord)) {
7338            return false;
7339        }
7340        try {
7341            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7342            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7343                return true;
7344            }
7345            return false;
7346        } catch (ClassCastException e) {
7347        }
7348        return false;
7349    }
7350
7351    @Override
7352    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7353        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7354                "getIntentForIntentSender()");
7355        if (!(pendingResult instanceof PendingIntentRecord)) {
7356            return null;
7357        }
7358        try {
7359            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7360            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7361        } catch (ClassCastException e) {
7362        }
7363        return null;
7364    }
7365
7366    @Override
7367    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7368        if (!(pendingResult instanceof PendingIntentRecord)) {
7369            return null;
7370        }
7371        try {
7372            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7373            synchronized (this) {
7374                return getTagForIntentSenderLocked(res, prefix);
7375            }
7376        } catch (ClassCastException e) {
7377        }
7378        return null;
7379    }
7380
7381    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7382        final Intent intent = res.key.requestIntent;
7383        if (intent != null) {
7384            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7385                    || res.lastTagPrefix.equals(prefix))) {
7386                return res.lastTag;
7387            }
7388            res.lastTagPrefix = prefix;
7389            final StringBuilder sb = new StringBuilder(128);
7390            if (prefix != null) {
7391                sb.append(prefix);
7392            }
7393            if (intent.getAction() != null) {
7394                sb.append(intent.getAction());
7395            } else if (intent.getComponent() != null) {
7396                intent.getComponent().appendShortString(sb);
7397            } else {
7398                sb.append("?");
7399            }
7400            return res.lastTag = sb.toString();
7401        }
7402        return null;
7403    }
7404
7405    @Override
7406    public void setProcessLimit(int max) {
7407        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7408                "setProcessLimit()");
7409        synchronized (this) {
7410            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7411            mProcessLimitOverride = max;
7412        }
7413        trimApplications();
7414    }
7415
7416    @Override
7417    public int getProcessLimit() {
7418        synchronized (this) {
7419            return mProcessLimitOverride;
7420        }
7421    }
7422
7423    void foregroundTokenDied(ForegroundToken token) {
7424        synchronized (ActivityManagerService.this) {
7425            synchronized (mPidsSelfLocked) {
7426                ForegroundToken cur
7427                    = mForegroundProcesses.get(token.pid);
7428                if (cur != token) {
7429                    return;
7430                }
7431                mForegroundProcesses.remove(token.pid);
7432                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7433                if (pr == null) {
7434                    return;
7435                }
7436                pr.forcingToForeground = null;
7437                updateProcessForegroundLocked(pr, false, false);
7438            }
7439            updateOomAdjLocked();
7440        }
7441    }
7442
7443    @Override
7444    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7445        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7446                "setProcessForeground()");
7447        synchronized(this) {
7448            boolean changed = false;
7449
7450            synchronized (mPidsSelfLocked) {
7451                ProcessRecord pr = mPidsSelfLocked.get(pid);
7452                if (pr == null && isForeground) {
7453                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7454                    return;
7455                }
7456                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7457                if (oldToken != null) {
7458                    oldToken.token.unlinkToDeath(oldToken, 0);
7459                    mForegroundProcesses.remove(pid);
7460                    if (pr != null) {
7461                        pr.forcingToForeground = null;
7462                    }
7463                    changed = true;
7464                }
7465                if (isForeground && token != null) {
7466                    ForegroundToken newToken = new ForegroundToken() {
7467                        @Override
7468                        public void binderDied() {
7469                            foregroundTokenDied(this);
7470                        }
7471                    };
7472                    newToken.pid = pid;
7473                    newToken.token = token;
7474                    try {
7475                        token.linkToDeath(newToken, 0);
7476                        mForegroundProcesses.put(pid, newToken);
7477                        pr.forcingToForeground = token;
7478                        changed = true;
7479                    } catch (RemoteException e) {
7480                        // If the process died while doing this, we will later
7481                        // do the cleanup with the process death link.
7482                    }
7483                }
7484            }
7485
7486            if (changed) {
7487                updateOomAdjLocked();
7488            }
7489        }
7490    }
7491
7492    @Override
7493    public boolean isAppForeground(int uid) throws RemoteException {
7494        synchronized (this) {
7495            UidRecord uidRec = mActiveUids.get(uid);
7496            if (uidRec == null || uidRec.idle) {
7497                return false;
7498            }
7499            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7500        }
7501    }
7502
7503    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7504    // be guarded by permission checking.
7505    int getUidState(int uid) {
7506        synchronized (this) {
7507            UidRecord uidRec = mActiveUids.get(uid);
7508            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7509        }
7510    }
7511
7512    @Override
7513    public boolean isInMultiWindowMode(IBinder token) {
7514        final long origId = Binder.clearCallingIdentity();
7515        try {
7516            synchronized(this) {
7517                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7518                if (r == null) {
7519                    return false;
7520                }
7521                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7522                return !r.task.mFullscreen;
7523            }
7524        } finally {
7525            Binder.restoreCallingIdentity(origId);
7526        }
7527    }
7528
7529    @Override
7530    public boolean isInPictureInPictureMode(IBinder token) {
7531        final long origId = Binder.clearCallingIdentity();
7532        try {
7533            synchronized(this) {
7534                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7535                if (stack == null) {
7536                    return false;
7537                }
7538                return stack.mStackId == PINNED_STACK_ID;
7539            }
7540        } finally {
7541            Binder.restoreCallingIdentity(origId);
7542        }
7543    }
7544
7545    @Override
7546    public void enterPictureInPictureMode(IBinder token) {
7547        enterPictureInPictureMode(token, DEFAULT_DISPLAY, -1f /* aspectRatio */,
7548                false /* checkAspectRatio */);
7549    }
7550
7551    @Override
7552    public void enterPictureInPictureModeWithAspectRatio(IBinder token, float aspectRatio) {
7553        enterPictureInPictureMode(token, DEFAULT_DISPLAY, aspectRatio, true /* checkAspectRatio */);
7554    }
7555
7556    @Override
7557    public void enterPictureInPictureModeOnMoveToBackground(IBinder token,
7558            boolean enterPictureInPictureOnMoveToBg) {
7559        final long origId = Binder.clearCallingIdentity();
7560        try {
7561            synchronized(this) {
7562                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7563                        "enterPictureInPictureModeOnMoveToBackground", token, -1f /* aspectRatio */,
7564                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7565
7566                r.supportsPipOnMoveToBackground = enterPictureInPictureOnMoveToBg;
7567            }
7568        } finally {
7569            Binder.restoreCallingIdentity(origId);
7570        }
7571    }
7572
7573    private void enterPictureInPictureMode(IBinder token, int displayId, float aspectRatio,
7574            boolean checkAspectRatio) {
7575        final long origId = Binder.clearCallingIdentity();
7576        try {
7577            synchronized(this) {
7578                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7579                        "enterPictureInPictureMode", token, aspectRatio, checkAspectRatio,
7580                        true /* checkActivityVisibility */);
7581                final Runnable enterPipRunnable = () -> {
7582                    r.pictureInPictureArgs.aspectRatio = aspectRatio;
7583                    enterPictureInPictureModeLocked(r, displayId, r.pictureInPictureArgs,
7584                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7585                };
7586
7587                if (isKeyguardLocked()) {
7588                    // If the keyguard is showing or occluded, then try and dismiss it before
7589                    // entering picture-in-picture (this will prompt the user to authenticate if the
7590                    // device is currently locked).
7591                    try {
7592                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7593                            @Override
7594                            public void onDismissError() throws RemoteException {
7595                                // Do nothing
7596                            }
7597
7598                            @Override
7599                            public void onDismissSucceeded() throws RemoteException {
7600                                mHandler.post(enterPipRunnable);
7601                            }
7602
7603                            @Override
7604                            public void onDismissCancelled() throws RemoteException {
7605                                // Do nothing
7606                            }
7607                        });
7608                    } catch (RemoteException e) {
7609                        // Local call
7610                    }
7611                } else {
7612                    // Enter picture in picture immediately otherwise
7613                    enterPipRunnable.run();
7614                }
7615            }
7616        } finally {
7617            Binder.restoreCallingIdentity(origId);
7618        }
7619    }
7620
7621    void enterPictureInPictureModeLocked(ActivityRecord r, int displayId,
7622            PictureInPictureArguments pipArgs, boolean moveHomeStackToFront, String reason) {
7623        final Rect bounds = isValidPictureInPictureAspectRatio(pipArgs.aspectRatio)
7624                ? mWindowManager.getPictureInPictureBounds(displayId, pipArgs.aspectRatio)
7625                : mWindowManager.getPictureInPictureDefaultBounds(displayId);
7626        mStackSupervisor.moveActivityToPinnedStackLocked(r, reason, bounds, moveHomeStackToFront);
7627        mWindowManager.setPictureInPictureActions(pipArgs.userActions);
7628    }
7629
7630    @Override
7631    public void setPictureInPictureAspectRatio(IBinder token, float aspectRatio) {
7632        final long origId = Binder.clearCallingIdentity();
7633        try {
7634            synchronized(this) {
7635                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7636                        "setPictureInPictureAspectRatio", token, aspectRatio,
7637                        true /* checkAspectRatio */, false /* checkActivityVisibility */);
7638
7639                r.pictureInPictureArgs.aspectRatio = aspectRatio;
7640                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7641                    // If the activity is already in picture-in-picture, update the pinned stack now
7642                    mWindowManager.setPictureInPictureAspectRatio(aspectRatio);
7643                }
7644            }
7645        } finally {
7646            Binder.restoreCallingIdentity(origId);
7647        }
7648    }
7649
7650    @Override
7651    public void setPictureInPictureActions(IBinder token, ParceledListSlice actionsList) {
7652        final long origId = Binder.clearCallingIdentity();
7653        try {
7654            synchronized(this) {
7655                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7656                        "setPictureInPictureActions", token, -1 /* aspectRatio */,
7657                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7658
7659                final List<RemoteAction> actions = actionsList.getList();
7660                if (actions.size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7661                    throw new IllegalArgumentException("setPictureInPictureActions: Invalid number"
7662                            + " of picture-in-picture actions.  Only a maximum of "
7663                            + ActivityManager.getMaxNumPictureInPictureActions()
7664                            + " actions allowed");
7665                }
7666
7667                r.pictureInPictureArgs.userActions = actions;
7668                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7669                    // If the activity is already in picture-in-picture, update the pinned stack now
7670                    mWindowManager.setPictureInPictureActions(actions);
7671                }
7672            }
7673        } finally {
7674            Binder.restoreCallingIdentity(origId);
7675        }
7676    }
7677
7678    private boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
7679        return mMinPipAspectRatio <= aspectRatio && aspectRatio <= mMaxPipAspectRatio;
7680    }
7681
7682    /**
7683     * Checks the state of the system and the activity associated with the given {@param token} to
7684     * verify that picture-in-picture is supported for that activity.
7685     *
7686     * @param checkAspectRatio whether or not to check {@param aspectRatio} is within a valid range
7687     * @param checkActivityVisibility whether or not to enforce that the activity is currently
7688     *                                visible
7689     *
7690     * @return the activity record for the given {@param token} if all the checks pass.
7691     */
7692    private ActivityRecord ensureValidPictureInPictureActivityLocked(String caller, IBinder token,
7693            float aspectRatio, boolean checkAspectRatio, boolean checkActivityVisibility) {
7694        if (!mSupportsPictureInPicture) {
7695            throw new IllegalStateException(caller
7696                    + ": Device doesn't support picture-in-picture mode.");
7697        }
7698
7699        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7700        if (r == null) {
7701            throw new IllegalStateException(caller
7702                    + ": Can't find activity for token=" + token);
7703        }
7704
7705        if (!r.canEnterPictureInPicture(checkActivityVisibility)) {
7706            throw new IllegalArgumentException(caller
7707                    + ": Current activity does not support picture-in-picture or is not "
7708                    + "visible r=" + r);
7709        }
7710
7711        if (r.getStack().isHomeStack()) {
7712            throw new IllegalStateException(caller
7713                    + ": Activities on the home stack not supported");
7714        }
7715
7716        if (checkAspectRatio && !isValidPictureInPictureAspectRatio(aspectRatio)) {
7717            throw new IllegalArgumentException(String.format(caller
7718                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7719                            mMinPipAspectRatio, mMaxPipAspectRatio));
7720        }
7721
7722        return r;
7723    }
7724
7725    // =========================================================
7726    // PROCESS INFO
7727    // =========================================================
7728
7729    static class ProcessInfoService extends IProcessInfoService.Stub {
7730        final ActivityManagerService mActivityManagerService;
7731        ProcessInfoService(ActivityManagerService activityManagerService) {
7732            mActivityManagerService = activityManagerService;
7733        }
7734
7735        @Override
7736        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7737            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7738                    /*in*/ pids, /*out*/ states, null);
7739        }
7740
7741        @Override
7742        public void getProcessStatesAndOomScoresFromPids(
7743                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7744            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7745                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7746        }
7747    }
7748
7749    /**
7750     * For each PID in the given input array, write the current process state
7751     * for that process into the states array, or -1 to indicate that no
7752     * process with the given PID exists. If scores array is provided, write
7753     * the oom score for the process into the scores array, with INVALID_ADJ
7754     * indicating the PID doesn't exist.
7755     */
7756    public void getProcessStatesAndOomScoresForPIDs(
7757            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7758        if (scores != null) {
7759            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7760                    "getProcessStatesAndOomScoresForPIDs()");
7761        }
7762
7763        if (pids == null) {
7764            throw new NullPointerException("pids");
7765        } else if (states == null) {
7766            throw new NullPointerException("states");
7767        } else if (pids.length != states.length) {
7768            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7769        } else if (scores != null && pids.length != scores.length) {
7770            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7771        }
7772
7773        synchronized (mPidsSelfLocked) {
7774            for (int i = 0; i < pids.length; i++) {
7775                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7776                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7777                        pr.curProcState;
7778                if (scores != null) {
7779                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7780                }
7781            }
7782        }
7783    }
7784
7785    // =========================================================
7786    // PERMISSIONS
7787    // =========================================================
7788
7789    static class PermissionController extends IPermissionController.Stub {
7790        ActivityManagerService mActivityManagerService;
7791        PermissionController(ActivityManagerService activityManagerService) {
7792            mActivityManagerService = activityManagerService;
7793        }
7794
7795        @Override
7796        public boolean checkPermission(String permission, int pid, int uid) {
7797            return mActivityManagerService.checkPermission(permission, pid,
7798                    uid) == PackageManager.PERMISSION_GRANTED;
7799        }
7800
7801        @Override
7802        public String[] getPackagesForUid(int uid) {
7803            return mActivityManagerService.mContext.getPackageManager()
7804                    .getPackagesForUid(uid);
7805        }
7806
7807        @Override
7808        public boolean isRuntimePermission(String permission) {
7809            try {
7810                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7811                        .getPermissionInfo(permission, 0);
7812                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7813                        == PermissionInfo.PROTECTION_DANGEROUS;
7814            } catch (NameNotFoundException nnfe) {
7815                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7816            }
7817            return false;
7818        }
7819    }
7820
7821    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7822        @Override
7823        public int checkComponentPermission(String permission, int pid, int uid,
7824                int owningUid, boolean exported) {
7825            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7826                    owningUid, exported);
7827        }
7828
7829        @Override
7830        public Object getAMSLock() {
7831            return ActivityManagerService.this;
7832        }
7833    }
7834
7835    /**
7836     * This can be called with or without the global lock held.
7837     */
7838    int checkComponentPermission(String permission, int pid, int uid,
7839            int owningUid, boolean exported) {
7840        if (pid == MY_PID) {
7841            return PackageManager.PERMISSION_GRANTED;
7842        }
7843        return ActivityManager.checkComponentPermission(permission, uid,
7844                owningUid, exported);
7845    }
7846
7847    /**
7848     * As the only public entry point for permissions checking, this method
7849     * can enforce the semantic that requesting a check on a null global
7850     * permission is automatically denied.  (Internally a null permission
7851     * string is used when calling {@link #checkComponentPermission} in cases
7852     * when only uid-based security is needed.)
7853     *
7854     * This can be called with or without the global lock held.
7855     */
7856    @Override
7857    public int checkPermission(String permission, int pid, int uid) {
7858        if (permission == null) {
7859            return PackageManager.PERMISSION_DENIED;
7860        }
7861        return checkComponentPermission(permission, pid, uid, -1, true);
7862    }
7863
7864    @Override
7865    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7866        if (permission == null) {
7867            return PackageManager.PERMISSION_DENIED;
7868        }
7869
7870        // We might be performing an operation on behalf of an indirect binder
7871        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7872        // client identity accordingly before proceeding.
7873        Identity tlsIdentity = sCallerIdentity.get();
7874        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7875            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7876                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7877            uid = tlsIdentity.uid;
7878            pid = tlsIdentity.pid;
7879        }
7880
7881        return checkComponentPermission(permission, pid, uid, -1, true);
7882    }
7883
7884    /**
7885     * Binder IPC calls go through the public entry point.
7886     * This can be called with or without the global lock held.
7887     */
7888    int checkCallingPermission(String permission) {
7889        return checkPermission(permission,
7890                Binder.getCallingPid(),
7891                UserHandle.getAppId(Binder.getCallingUid()));
7892    }
7893
7894    /**
7895     * This can be called with or without the global lock held.
7896     */
7897    void enforceCallingPermission(String permission, String func) {
7898        if (checkCallingPermission(permission)
7899                == PackageManager.PERMISSION_GRANTED) {
7900            return;
7901        }
7902
7903        String msg = "Permission Denial: " + func + " from pid="
7904                + Binder.getCallingPid()
7905                + ", uid=" + Binder.getCallingUid()
7906                + " requires " + permission;
7907        Slog.w(TAG, msg);
7908        throw new SecurityException(msg);
7909    }
7910
7911    /**
7912     * Determine if UID is holding permissions required to access {@link Uri} in
7913     * the given {@link ProviderInfo}. Final permission checking is always done
7914     * in {@link ContentProvider}.
7915     */
7916    private final boolean checkHoldingPermissionsLocked(
7917            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7918        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7919                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7920        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7921            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7922                    != PERMISSION_GRANTED) {
7923                return false;
7924            }
7925        }
7926        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7927    }
7928
7929    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7930            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7931        if (pi.applicationInfo.uid == uid) {
7932            return true;
7933        } else if (!pi.exported) {
7934            return false;
7935        }
7936
7937        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7938        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7939        try {
7940            // check if target holds top-level <provider> permissions
7941            if (!readMet && pi.readPermission != null && considerUidPermissions
7942                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7943                readMet = true;
7944            }
7945            if (!writeMet && pi.writePermission != null && considerUidPermissions
7946                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7947                writeMet = true;
7948            }
7949
7950            // track if unprotected read/write is allowed; any denied
7951            // <path-permission> below removes this ability
7952            boolean allowDefaultRead = pi.readPermission == null;
7953            boolean allowDefaultWrite = pi.writePermission == null;
7954
7955            // check if target holds any <path-permission> that match uri
7956            final PathPermission[] pps = pi.pathPermissions;
7957            if (pps != null) {
7958                final String path = grantUri.uri.getPath();
7959                int i = pps.length;
7960                while (i > 0 && (!readMet || !writeMet)) {
7961                    i--;
7962                    PathPermission pp = pps[i];
7963                    if (pp.match(path)) {
7964                        if (!readMet) {
7965                            final String pprperm = pp.getReadPermission();
7966                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7967                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7968                                    + ": match=" + pp.match(path)
7969                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7970                            if (pprperm != null) {
7971                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7972                                        == PERMISSION_GRANTED) {
7973                                    readMet = true;
7974                                } else {
7975                                    allowDefaultRead = false;
7976                                }
7977                            }
7978                        }
7979                        if (!writeMet) {
7980                            final String ppwperm = pp.getWritePermission();
7981                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7983                                    + ": match=" + pp.match(path)
7984                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7985                            if (ppwperm != null) {
7986                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7987                                        == PERMISSION_GRANTED) {
7988                                    writeMet = true;
7989                                } else {
7990                                    allowDefaultWrite = false;
7991                                }
7992                            }
7993                        }
7994                    }
7995                }
7996            }
7997
7998            // grant unprotected <provider> read/write, if not blocked by
7999            // <path-permission> above
8000            if (allowDefaultRead) readMet = true;
8001            if (allowDefaultWrite) writeMet = true;
8002
8003        } catch (RemoteException e) {
8004            return false;
8005        }
8006
8007        return readMet && writeMet;
8008    }
8009
8010    public int getAppStartMode(int uid, String packageName) {
8011        synchronized (this) {
8012            return checkAllowBackgroundLocked(uid, packageName, -1, false);
8013        }
8014    }
8015
8016    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
8017            boolean alwaysRestrict) {
8018        UidRecord uidRec = mActiveUids.get(uid);
8019        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8020            boolean ephemeral;
8021            if (uidRec == null) {
8022                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8023                        UserHandle.getUserId(uid), packageName);
8024            } else {
8025                ephemeral = uidRec.ephemeral;
8026            }
8027
8028            if (ephemeral) {
8029                // We are hard-core about ephemeral apps not running in the background.
8030                return ActivityManager.APP_START_MODE_DISABLED;
8031            } else {
8032                if (callingPid >= 0) {
8033                    ProcessRecord proc;
8034                    synchronized (mPidsSelfLocked) {
8035                        proc = mPidsSelfLocked.get(callingPid);
8036                    }
8037                    if (proc != null && proc.curProcState
8038                            < ActivityManager.PROCESS_STATE_RECEIVER) {
8039                        // Whoever is instigating this is in the foreground, so we will allow it
8040                        // to go through.
8041                        return ActivityManager.APP_START_MODE_NORMAL;
8042                    }
8043                }
8044                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
8045                        packageName) != AppOpsManager.MODE_ALLOWED) {
8046                    return ActivityManager.APP_START_MODE_DELAYED;
8047                }
8048            }
8049        }
8050        return ActivityManager.APP_START_MODE_NORMAL;
8051    }
8052
8053    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8054        ProviderInfo pi = null;
8055        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8056        if (cpr != null) {
8057            pi = cpr.info;
8058        } else {
8059            try {
8060                pi = AppGlobals.getPackageManager().resolveContentProvider(
8061                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8062                        userHandle);
8063            } catch (RemoteException ex) {
8064            }
8065        }
8066        return pi;
8067    }
8068
8069    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8070        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8071        if (targetUris != null) {
8072            return targetUris.get(grantUri);
8073        }
8074        return null;
8075    }
8076
8077    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8078            String targetPkg, int targetUid, GrantUri grantUri) {
8079        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8080        if (targetUris == null) {
8081            targetUris = Maps.newArrayMap();
8082            mGrantedUriPermissions.put(targetUid, targetUris);
8083        }
8084
8085        UriPermission perm = targetUris.get(grantUri);
8086        if (perm == null) {
8087            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8088            targetUris.put(grantUri, perm);
8089        }
8090
8091        return perm;
8092    }
8093
8094    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8095            final int modeFlags) {
8096        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8097        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8098                : UriPermission.STRENGTH_OWNED;
8099
8100        // Root gets to do everything.
8101        if (uid == 0) {
8102            return true;
8103        }
8104
8105        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8106        if (perms == null) return false;
8107
8108        // First look for exact match
8109        final UriPermission exactPerm = perms.get(grantUri);
8110        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8111            return true;
8112        }
8113
8114        // No exact match, look for prefixes
8115        final int N = perms.size();
8116        for (int i = 0; i < N; i++) {
8117            final UriPermission perm = perms.valueAt(i);
8118            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8119                    && perm.getStrength(modeFlags) >= minStrength) {
8120                return true;
8121            }
8122        }
8123
8124        return false;
8125    }
8126
8127    /**
8128     * @param uri This uri must NOT contain an embedded userId.
8129     * @param userId The userId in which the uri is to be resolved.
8130     */
8131    @Override
8132    public int checkUriPermission(Uri uri, int pid, int uid,
8133            final int modeFlags, int userId, IBinder callerToken) {
8134        enforceNotIsolatedCaller("checkUriPermission");
8135
8136        // Another redirected-binder-call permissions check as in
8137        // {@link checkPermissionWithToken}.
8138        Identity tlsIdentity = sCallerIdentity.get();
8139        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8140            uid = tlsIdentity.uid;
8141            pid = tlsIdentity.pid;
8142        }
8143
8144        // Our own process gets to do everything.
8145        if (pid == MY_PID) {
8146            return PackageManager.PERMISSION_GRANTED;
8147        }
8148        synchronized (this) {
8149            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8150                    ? PackageManager.PERMISSION_GRANTED
8151                    : PackageManager.PERMISSION_DENIED;
8152        }
8153    }
8154
8155    /**
8156     * Check if the targetPkg can be granted permission to access uri by
8157     * the callingUid using the given modeFlags.  Throws a security exception
8158     * if callingUid is not allowed to do this.  Returns the uid of the target
8159     * if the URI permission grant should be performed; returns -1 if it is not
8160     * needed (for example targetPkg already has permission to access the URI).
8161     * If you already know the uid of the target, you can supply it in
8162     * lastTargetUid else set that to -1.
8163     */
8164    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8165            final int modeFlags, int lastTargetUid) {
8166        if (!Intent.isAccessUriMode(modeFlags)) {
8167            return -1;
8168        }
8169
8170        if (targetPkg != null) {
8171            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172                    "Checking grant " + targetPkg + " permission to " + grantUri);
8173        }
8174
8175        final IPackageManager pm = AppGlobals.getPackageManager();
8176
8177        // If this is not a content: uri, we can't do anything with it.
8178        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8179            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8180                    "Can't grant URI permission for non-content URI: " + grantUri);
8181            return -1;
8182        }
8183
8184        final String authority = grantUri.uri.getAuthority();
8185        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8186                MATCH_DEBUG_TRIAGED_MISSING);
8187        if (pi == null) {
8188            Slog.w(TAG, "No content provider found for permission check: " +
8189                    grantUri.uri.toSafeString());
8190            return -1;
8191        }
8192
8193        int targetUid = lastTargetUid;
8194        if (targetUid < 0 && targetPkg != null) {
8195            try {
8196                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8197                        UserHandle.getUserId(callingUid));
8198                if (targetUid < 0) {
8199                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8200                            "Can't grant URI permission no uid for: " + targetPkg);
8201                    return -1;
8202                }
8203            } catch (RemoteException ex) {
8204                return -1;
8205            }
8206        }
8207
8208        // If we're extending a persistable grant, then we always need to create
8209        // the grant data structure so that take/release APIs work
8210        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8211            return targetUid;
8212        }
8213
8214        if (targetUid >= 0) {
8215            // First...  does the target actually need this permission?
8216            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8217                // No need to grant the target this permission.
8218                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8219                        "Target " + targetPkg + " already has full permission to " + grantUri);
8220                return -1;
8221            }
8222        } else {
8223            // First...  there is no target package, so can anyone access it?
8224            boolean allowed = pi.exported;
8225            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8226                if (pi.readPermission != null) {
8227                    allowed = false;
8228                }
8229            }
8230            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8231                if (pi.writePermission != null) {
8232                    allowed = false;
8233                }
8234            }
8235            if (allowed) {
8236                return -1;
8237            }
8238        }
8239
8240        /* There is a special cross user grant if:
8241         * - The target is on another user.
8242         * - Apps on the current user can access the uri without any uid permissions.
8243         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8244         * grant uri permissions.
8245         */
8246        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8247                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8248                modeFlags, false /*without considering the uid permissions*/);
8249
8250        // Second...  is the provider allowing granting of URI permissions?
8251        if (!specialCrossUserGrant) {
8252            if (!pi.grantUriPermissions) {
8253                throw new SecurityException("Provider " + pi.packageName
8254                        + "/" + pi.name
8255                        + " does not allow granting of Uri permissions (uri "
8256                        + grantUri + ")");
8257            }
8258            if (pi.uriPermissionPatterns != null) {
8259                final int N = pi.uriPermissionPatterns.length;
8260                boolean allowed = false;
8261                for (int i=0; i<N; i++) {
8262                    if (pi.uriPermissionPatterns[i] != null
8263                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8264                        allowed = true;
8265                        break;
8266                    }
8267                }
8268                if (!allowed) {
8269                    throw new SecurityException("Provider " + pi.packageName
8270                            + "/" + pi.name
8271                            + " does not allow granting of permission to path of Uri "
8272                            + grantUri);
8273                }
8274            }
8275        }
8276
8277        // Third...  does the caller itself have permission to access
8278        // this uri?
8279        final int callingAppId = UserHandle.getAppId(callingUid);
8280        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8281            Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8282                    + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8283            return -1;
8284        } else {
8285            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8286                // Require they hold a strong enough Uri permission
8287                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8288                    throw new SecurityException("Uid " + callingUid
8289                            + " does not have permission to uri " + grantUri);
8290                }
8291            }
8292        }
8293        return targetUid;
8294    }
8295
8296    /**
8297     * @param uri This uri must NOT contain an embedded userId.
8298     * @param userId The userId in which the uri is to be resolved.
8299     */
8300    @Override
8301    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8302            final int modeFlags, int userId) {
8303        enforceNotIsolatedCaller("checkGrantUriPermission");
8304        synchronized(this) {
8305            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8306                    new GrantUri(userId, uri, false), modeFlags, -1);
8307        }
8308    }
8309
8310    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8311            final int modeFlags, UriPermissionOwner owner) {
8312        if (!Intent.isAccessUriMode(modeFlags)) {
8313            return;
8314        }
8315
8316        // So here we are: the caller has the assumed permission
8317        // to the uri, and the target doesn't.  Let's now give this to
8318        // the target.
8319
8320        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8321                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8322
8323        final String authority = grantUri.uri.getAuthority();
8324        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8325                MATCH_DEBUG_TRIAGED_MISSING);
8326        if (pi == null) {
8327            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8328            return;
8329        }
8330
8331        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8332            grantUri.prefix = true;
8333        }
8334        final UriPermission perm = findOrCreateUriPermissionLocked(
8335                pi.packageName, targetPkg, targetUid, grantUri);
8336        perm.grantModes(modeFlags, owner);
8337    }
8338
8339    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8340            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8341        if (targetPkg == null) {
8342            throw new NullPointerException("targetPkg");
8343        }
8344        int targetUid;
8345        final IPackageManager pm = AppGlobals.getPackageManager();
8346        try {
8347            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8348        } catch (RemoteException ex) {
8349            return;
8350        }
8351
8352        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8353                targetUid);
8354        if (targetUid < 0) {
8355            return;
8356        }
8357
8358        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8359                owner);
8360    }
8361
8362    static class NeededUriGrants extends ArrayList<GrantUri> {
8363        final String targetPkg;
8364        final int targetUid;
8365        final int flags;
8366
8367        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8368            this.targetPkg = targetPkg;
8369            this.targetUid = targetUid;
8370            this.flags = flags;
8371        }
8372    }
8373
8374    /**
8375     * Like checkGrantUriPermissionLocked, but takes an Intent.
8376     */
8377    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8378            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8379        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8380                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8381                + " clip=" + (intent != null ? intent.getClipData() : null)
8382                + " from " + intent + "; flags=0x"
8383                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8384
8385        if (targetPkg == null) {
8386            throw new NullPointerException("targetPkg");
8387        }
8388
8389        if (intent == null) {
8390            return null;
8391        }
8392        Uri data = intent.getData();
8393        ClipData clip = intent.getClipData();
8394        if (data == null && clip == null) {
8395            return null;
8396        }
8397        // Default userId for uris in the intent (if they don't specify it themselves)
8398        int contentUserHint = intent.getContentUserHint();
8399        if (contentUserHint == UserHandle.USER_CURRENT) {
8400            contentUserHint = UserHandle.getUserId(callingUid);
8401        }
8402        final IPackageManager pm = AppGlobals.getPackageManager();
8403        int targetUid;
8404        if (needed != null) {
8405            targetUid = needed.targetUid;
8406        } else {
8407            try {
8408                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8409                        targetUserId);
8410            } catch (RemoteException ex) {
8411                return null;
8412            }
8413            if (targetUid < 0) {
8414                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8415                        "Can't grant URI permission no uid for: " + targetPkg
8416                        + " on user " + targetUserId);
8417                return null;
8418            }
8419        }
8420        if (data != null) {
8421            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8422            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8423                    targetUid);
8424            if (targetUid > 0) {
8425                if (needed == null) {
8426                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8427                }
8428                needed.add(grantUri);
8429            }
8430        }
8431        if (clip != null) {
8432            for (int i=0; i<clip.getItemCount(); i++) {
8433                Uri uri = clip.getItemAt(i).getUri();
8434                if (uri != null) {
8435                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8436                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8437                            targetUid);
8438                    if (targetUid > 0) {
8439                        if (needed == null) {
8440                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8441                        }
8442                        needed.add(grantUri);
8443                    }
8444                } else {
8445                    Intent clipIntent = clip.getItemAt(i).getIntent();
8446                    if (clipIntent != null) {
8447                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8448                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8449                        if (newNeeded != null) {
8450                            needed = newNeeded;
8451                        }
8452                    }
8453                }
8454            }
8455        }
8456
8457        return needed;
8458    }
8459
8460    /**
8461     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8462     */
8463    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8464            UriPermissionOwner owner) {
8465        if (needed != null) {
8466            for (int i=0; i<needed.size(); i++) {
8467                GrantUri grantUri = needed.get(i);
8468                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8469                        grantUri, needed.flags, owner);
8470            }
8471        }
8472    }
8473
8474    void grantUriPermissionFromIntentLocked(int callingUid,
8475            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8476        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8477                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8478        if (needed == null) {
8479            return;
8480        }
8481
8482        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8483    }
8484
8485    /**
8486     * @param uri This uri must NOT contain an embedded userId.
8487     * @param userId The userId in which the uri is to be resolved.
8488     */
8489    @Override
8490    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8491            final int modeFlags, int userId) {
8492        enforceNotIsolatedCaller("grantUriPermission");
8493        GrantUri grantUri = new GrantUri(userId, uri, false);
8494        synchronized(this) {
8495            final ProcessRecord r = getRecordForAppLocked(caller);
8496            if (r == null) {
8497                throw new SecurityException("Unable to find app for caller "
8498                        + caller
8499                        + " when granting permission to uri " + grantUri);
8500            }
8501            if (targetPkg == null) {
8502                throw new IllegalArgumentException("null target");
8503            }
8504            if (grantUri == null) {
8505                throw new IllegalArgumentException("null uri");
8506            }
8507
8508            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8509                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8510                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8511                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8512
8513            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8514                    UserHandle.getUserId(r.uid));
8515        }
8516    }
8517
8518    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8519        if (perm.modeFlags == 0) {
8520            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8521                    perm.targetUid);
8522            if (perms != null) {
8523                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8524                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8525
8526                perms.remove(perm.uri);
8527                if (perms.isEmpty()) {
8528                    mGrantedUriPermissions.remove(perm.targetUid);
8529                }
8530            }
8531        }
8532    }
8533
8534    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8535        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8536                "Revoking all granted permissions to " + grantUri);
8537
8538        final IPackageManager pm = AppGlobals.getPackageManager();
8539        final String authority = grantUri.uri.getAuthority();
8540        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8541                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8542        if (pi == null) {
8543            Slog.w(TAG, "No content provider found for permission revoke: "
8544                    + grantUri.toSafeString());
8545            return;
8546        }
8547
8548        // Does the caller have this permission on the URI?
8549        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8550            // If they don't have direct access to the URI, then revoke any
8551            // ownerless URI permissions that have been granted to them.
8552            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8553            if (perms != null) {
8554                boolean persistChanged = false;
8555                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8556                    final UriPermission perm = it.next();
8557                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8558                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8559                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8560                                "Revoking non-owned " + perm.targetUid
8561                                + " permission to " + perm.uri);
8562                        persistChanged |= perm.revokeModes(
8563                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8564                        if (perm.modeFlags == 0) {
8565                            it.remove();
8566                        }
8567                    }
8568                }
8569                if (perms.isEmpty()) {
8570                    mGrantedUriPermissions.remove(callingUid);
8571                }
8572                if (persistChanged) {
8573                    schedulePersistUriGrants();
8574                }
8575            }
8576            return;
8577        }
8578
8579        boolean persistChanged = false;
8580
8581        // Go through all of the permissions and remove any that match.
8582        int N = mGrantedUriPermissions.size();
8583        for (int i = 0; i < N; i++) {
8584            final int targetUid = mGrantedUriPermissions.keyAt(i);
8585            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8586
8587            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8588                final UriPermission perm = it.next();
8589                if (perm.uri.sourceUserId == grantUri.sourceUserId
8590                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8591                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8592                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8593                    persistChanged |= perm.revokeModes(
8594                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8595                    if (perm.modeFlags == 0) {
8596                        it.remove();
8597                    }
8598                }
8599            }
8600
8601            if (perms.isEmpty()) {
8602                mGrantedUriPermissions.remove(targetUid);
8603                N--;
8604                i--;
8605            }
8606        }
8607
8608        if (persistChanged) {
8609            schedulePersistUriGrants();
8610        }
8611    }
8612
8613    /**
8614     * @param uri This uri must NOT contain an embedded userId.
8615     * @param userId The userId in which the uri is to be resolved.
8616     */
8617    @Override
8618    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8619            int userId) {
8620        enforceNotIsolatedCaller("revokeUriPermission");
8621        synchronized(this) {
8622            final ProcessRecord r = getRecordForAppLocked(caller);
8623            if (r == null) {
8624                throw new SecurityException("Unable to find app for caller "
8625                        + caller
8626                        + " when revoking permission to uri " + uri);
8627            }
8628            if (uri == null) {
8629                Slog.w(TAG, "revokeUriPermission: null uri");
8630                return;
8631            }
8632
8633            if (!Intent.isAccessUriMode(modeFlags)) {
8634                return;
8635            }
8636
8637            final String authority = uri.getAuthority();
8638            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8639                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8640            if (pi == null) {
8641                Slog.w(TAG, "No content provider found for permission revoke: "
8642                        + uri.toSafeString());
8643                return;
8644            }
8645
8646            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8647        }
8648    }
8649
8650    /**
8651     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8652     * given package.
8653     *
8654     * @param packageName Package name to match, or {@code null} to apply to all
8655     *            packages.
8656     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8657     *            to all users.
8658     * @param persistable If persistable grants should be removed.
8659     */
8660    private void removeUriPermissionsForPackageLocked(
8661            String packageName, int userHandle, boolean persistable) {
8662        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8663            throw new IllegalArgumentException("Must narrow by either package or user");
8664        }
8665
8666        boolean persistChanged = false;
8667
8668        int N = mGrantedUriPermissions.size();
8669        for (int i = 0; i < N; i++) {
8670            final int targetUid = mGrantedUriPermissions.keyAt(i);
8671            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8672
8673            // Only inspect grants matching user
8674            if (userHandle == UserHandle.USER_ALL
8675                    || userHandle == UserHandle.getUserId(targetUid)) {
8676                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8677                    final UriPermission perm = it.next();
8678
8679                    // Only inspect grants matching package
8680                    if (packageName == null || perm.sourcePkg.equals(packageName)
8681                            || perm.targetPkg.equals(packageName)) {
8682                        // Hacky solution as part of fixing a security bug; ignore
8683                        // grants associated with DownloadManager so we don't have
8684                        // to immediately launch it to regrant the permissions
8685                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8686                                && !persistable) continue;
8687
8688                        persistChanged |= perm.revokeModes(persistable
8689                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8690
8691                        // Only remove when no modes remain; any persisted grants
8692                        // will keep this alive.
8693                        if (perm.modeFlags == 0) {
8694                            it.remove();
8695                        }
8696                    }
8697                }
8698
8699                if (perms.isEmpty()) {
8700                    mGrantedUriPermissions.remove(targetUid);
8701                    N--;
8702                    i--;
8703                }
8704            }
8705        }
8706
8707        if (persistChanged) {
8708            schedulePersistUriGrants();
8709        }
8710    }
8711
8712    @Override
8713    public IBinder newUriPermissionOwner(String name) {
8714        enforceNotIsolatedCaller("newUriPermissionOwner");
8715        synchronized(this) {
8716            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8717            return owner.getExternalTokenLocked();
8718        }
8719    }
8720
8721    @Override
8722    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8723        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8724        synchronized(this) {
8725            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8726            if (r == null) {
8727                throw new IllegalArgumentException("Activity does not exist; token="
8728                        + activityToken);
8729            }
8730            return r.getUriPermissionsLocked().getExternalTokenLocked();
8731        }
8732    }
8733    /**
8734     * @param uri This uri must NOT contain an embedded userId.
8735     * @param sourceUserId The userId in which the uri is to be resolved.
8736     * @param targetUserId The userId of the app that receives the grant.
8737     */
8738    @Override
8739    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8740            final int modeFlags, int sourceUserId, int targetUserId) {
8741        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8742                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8743                "grantUriPermissionFromOwner", null);
8744        synchronized(this) {
8745            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8746            if (owner == null) {
8747                throw new IllegalArgumentException("Unknown owner: " + token);
8748            }
8749            if (fromUid != Binder.getCallingUid()) {
8750                if (Binder.getCallingUid() != Process.myUid()) {
8751                    // Only system code can grant URI permissions on behalf
8752                    // of other users.
8753                    throw new SecurityException("nice try");
8754                }
8755            }
8756            if (targetPkg == null) {
8757                throw new IllegalArgumentException("null target");
8758            }
8759            if (uri == null) {
8760                throw new IllegalArgumentException("null uri");
8761            }
8762
8763            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8764                    modeFlags, owner, targetUserId);
8765        }
8766    }
8767
8768    /**
8769     * @param uri This uri must NOT contain an embedded userId.
8770     * @param userId The userId in which the uri is to be resolved.
8771     */
8772    @Override
8773    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8774        synchronized(this) {
8775            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8776            if (owner == null) {
8777                throw new IllegalArgumentException("Unknown owner: " + token);
8778            }
8779
8780            if (uri == null) {
8781                owner.removeUriPermissionsLocked(mode);
8782            } else {
8783                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8784                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8785            }
8786        }
8787    }
8788
8789    private void schedulePersistUriGrants() {
8790        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8791            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8792                    10 * DateUtils.SECOND_IN_MILLIS);
8793        }
8794    }
8795
8796    private void writeGrantedUriPermissions() {
8797        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8798
8799        // Snapshot permissions so we can persist without lock
8800        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8801        synchronized (this) {
8802            final int size = mGrantedUriPermissions.size();
8803            for (int i = 0; i < size; i++) {
8804                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8805                for (UriPermission perm : perms.values()) {
8806                    if (perm.persistedModeFlags != 0) {
8807                        persist.add(perm.snapshot());
8808                    }
8809                }
8810            }
8811        }
8812
8813        FileOutputStream fos = null;
8814        try {
8815            fos = mGrantFile.startWrite();
8816
8817            XmlSerializer out = new FastXmlSerializer();
8818            out.setOutput(fos, StandardCharsets.UTF_8.name());
8819            out.startDocument(null, true);
8820            out.startTag(null, TAG_URI_GRANTS);
8821            for (UriPermission.Snapshot perm : persist) {
8822                out.startTag(null, TAG_URI_GRANT);
8823                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8824                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8825                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8826                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8827                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8828                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8829                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8830                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8831                out.endTag(null, TAG_URI_GRANT);
8832            }
8833            out.endTag(null, TAG_URI_GRANTS);
8834            out.endDocument();
8835
8836            mGrantFile.finishWrite(fos);
8837        } catch (IOException e) {
8838            if (fos != null) {
8839                mGrantFile.failWrite(fos);
8840            }
8841        }
8842    }
8843
8844    private void readGrantedUriPermissionsLocked() {
8845        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8846
8847        final long now = System.currentTimeMillis();
8848
8849        FileInputStream fis = null;
8850        try {
8851            fis = mGrantFile.openRead();
8852            final XmlPullParser in = Xml.newPullParser();
8853            in.setInput(fis, StandardCharsets.UTF_8.name());
8854
8855            int type;
8856            while ((type = in.next()) != END_DOCUMENT) {
8857                final String tag = in.getName();
8858                if (type == START_TAG) {
8859                    if (TAG_URI_GRANT.equals(tag)) {
8860                        final int sourceUserId;
8861                        final int targetUserId;
8862                        final int userHandle = readIntAttribute(in,
8863                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8864                        if (userHandle != UserHandle.USER_NULL) {
8865                            // For backwards compatibility.
8866                            sourceUserId = userHandle;
8867                            targetUserId = userHandle;
8868                        } else {
8869                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8870                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8871                        }
8872                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8873                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8874                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8875                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8876                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8877                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8878
8879                        // Sanity check that provider still belongs to source package
8880                        // Both direct boot aware and unaware packages are fine as we
8881                        // will do filtering at query time to avoid multiple parsing.
8882                        final ProviderInfo pi = getProviderInfoLocked(
8883                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8884                                        | MATCH_DIRECT_BOOT_UNAWARE);
8885                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8886                            int targetUid = -1;
8887                            try {
8888                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8889                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8890                            } catch (RemoteException e) {
8891                            }
8892                            if (targetUid != -1) {
8893                                final UriPermission perm = findOrCreateUriPermissionLocked(
8894                                        sourcePkg, targetPkg, targetUid,
8895                                        new GrantUri(sourceUserId, uri, prefix));
8896                                perm.initPersistedModes(modeFlags, createdTime);
8897                            }
8898                        } else {
8899                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8900                                    + " but instead found " + pi);
8901                        }
8902                    }
8903                }
8904            }
8905        } catch (FileNotFoundException e) {
8906            // Missing grants is okay
8907        } catch (IOException e) {
8908            Slog.wtf(TAG, "Failed reading Uri grants", e);
8909        } catch (XmlPullParserException e) {
8910            Slog.wtf(TAG, "Failed reading Uri grants", e);
8911        } finally {
8912            IoUtils.closeQuietly(fis);
8913        }
8914    }
8915
8916    /**
8917     * @param uri This uri must NOT contain an embedded userId.
8918     * @param userId The userId in which the uri is to be resolved.
8919     */
8920    @Override
8921    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8922        enforceNotIsolatedCaller("takePersistableUriPermission");
8923
8924        Preconditions.checkFlagsArgument(modeFlags,
8925                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8926
8927        synchronized (this) {
8928            final int callingUid = Binder.getCallingUid();
8929            boolean persistChanged = false;
8930            GrantUri grantUri = new GrantUri(userId, uri, false);
8931
8932            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8933                    new GrantUri(userId, uri, false));
8934            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8935                    new GrantUri(userId, uri, true));
8936
8937            final boolean exactValid = (exactPerm != null)
8938                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8939            final boolean prefixValid = (prefixPerm != null)
8940                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8941
8942            if (!(exactValid || prefixValid)) {
8943                throw new SecurityException("No persistable permission grants found for UID "
8944                        + callingUid + " and Uri " + grantUri.toSafeString());
8945            }
8946
8947            if (exactValid) {
8948                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8949            }
8950            if (prefixValid) {
8951                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8952            }
8953
8954            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8955
8956            if (persistChanged) {
8957                schedulePersistUriGrants();
8958            }
8959        }
8960    }
8961
8962    /**
8963     * @param uri This uri must NOT contain an embedded userId.
8964     * @param userId The userId in which the uri is to be resolved.
8965     */
8966    @Override
8967    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8968        enforceNotIsolatedCaller("releasePersistableUriPermission");
8969
8970        Preconditions.checkFlagsArgument(modeFlags,
8971                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8972
8973        synchronized (this) {
8974            final int callingUid = Binder.getCallingUid();
8975            boolean persistChanged = false;
8976
8977            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8978                    new GrantUri(userId, uri, false));
8979            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8980                    new GrantUri(userId, uri, true));
8981            if (exactPerm == null && prefixPerm == null) {
8982                throw new SecurityException("No permission grants found for UID " + callingUid
8983                        + " and Uri " + uri.toSafeString());
8984            }
8985
8986            if (exactPerm != null) {
8987                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8988                removeUriPermissionIfNeededLocked(exactPerm);
8989            }
8990            if (prefixPerm != null) {
8991                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8992                removeUriPermissionIfNeededLocked(prefixPerm);
8993            }
8994
8995            if (persistChanged) {
8996                schedulePersistUriGrants();
8997            }
8998        }
8999    }
9000
9001    /**
9002     * Prune any older {@link UriPermission} for the given UID until outstanding
9003     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9004     *
9005     * @return if any mutations occured that require persisting.
9006     */
9007    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9008        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9009        if (perms == null) return false;
9010        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9011
9012        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9013        for (UriPermission perm : perms.values()) {
9014            if (perm.persistedModeFlags != 0) {
9015                persisted.add(perm);
9016            }
9017        }
9018
9019        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9020        if (trimCount <= 0) return false;
9021
9022        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9023        for (int i = 0; i < trimCount; i++) {
9024            final UriPermission perm = persisted.get(i);
9025
9026            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9027                    "Trimming grant created at " + perm.persistedCreateTime);
9028
9029            perm.releasePersistableModes(~0);
9030            removeUriPermissionIfNeededLocked(perm);
9031        }
9032
9033        return true;
9034    }
9035
9036    @Override
9037    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9038            String packageName, boolean incoming) {
9039        enforceNotIsolatedCaller("getPersistedUriPermissions");
9040        Preconditions.checkNotNull(packageName, "packageName");
9041
9042        final int callingUid = Binder.getCallingUid();
9043        final int callingUserId = UserHandle.getUserId(callingUid);
9044        final IPackageManager pm = AppGlobals.getPackageManager();
9045        try {
9046            final int packageUid = pm.getPackageUid(packageName,
9047                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9048            if (packageUid != callingUid) {
9049                throw new SecurityException(
9050                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9051            }
9052        } catch (RemoteException e) {
9053            throw new SecurityException("Failed to verify package name ownership");
9054        }
9055
9056        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9057        synchronized (this) {
9058            if (incoming) {
9059                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9060                        callingUid);
9061                if (perms == null) {
9062                    Slog.w(TAG, "No permission grants found for " + packageName);
9063                } else {
9064                    for (UriPermission perm : perms.values()) {
9065                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9066                            result.add(perm.buildPersistedPublicApiObject());
9067                        }
9068                    }
9069                }
9070            } else {
9071                final int size = mGrantedUriPermissions.size();
9072                for (int i = 0; i < size; i++) {
9073                    final ArrayMap<GrantUri, UriPermission> perms =
9074                            mGrantedUriPermissions.valueAt(i);
9075                    for (UriPermission perm : perms.values()) {
9076                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9077                            result.add(perm.buildPersistedPublicApiObject());
9078                        }
9079                    }
9080                }
9081            }
9082        }
9083        return new ParceledListSlice<android.content.UriPermission>(result);
9084    }
9085
9086    @Override
9087    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9088            String packageName, int userId) {
9089        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9090                "getGrantedUriPermissions");
9091
9092        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9093        synchronized (this) {
9094            final int size = mGrantedUriPermissions.size();
9095            for (int i = 0; i < size; i++) {
9096                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9097                for (UriPermission perm : perms.values()) {
9098                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9099                            && perm.persistedModeFlags != 0) {
9100                        result.add(perm.buildPersistedPublicApiObject());
9101                    }
9102                }
9103            }
9104        }
9105        return new ParceledListSlice<android.content.UriPermission>(result);
9106    }
9107
9108    @Override
9109    public void clearGrantedUriPermissions(String packageName, int userId) {
9110        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9111                "clearGrantedUriPermissions");
9112        removeUriPermissionsForPackageLocked(packageName, userId, true);
9113    }
9114
9115    @Override
9116    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9117        synchronized (this) {
9118            ProcessRecord app =
9119                who != null ? getRecordForAppLocked(who) : null;
9120            if (app == null) return;
9121
9122            Message msg = Message.obtain();
9123            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9124            msg.obj = app;
9125            msg.arg1 = waiting ? 1 : 0;
9126            mUiHandler.sendMessage(msg);
9127        }
9128    }
9129
9130    @Override
9131    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9132        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9133        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9134        outInfo.availMem = Process.getFreeMemory();
9135        outInfo.totalMem = Process.getTotalMemory();
9136        outInfo.threshold = homeAppMem;
9137        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9138        outInfo.hiddenAppThreshold = cachedAppMem;
9139        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9140                ProcessList.SERVICE_ADJ);
9141        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9142                ProcessList.VISIBLE_APP_ADJ);
9143        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9144                ProcessList.FOREGROUND_APP_ADJ);
9145    }
9146
9147    // =========================================================
9148    // TASK MANAGEMENT
9149    // =========================================================
9150
9151    @Override
9152    public List<IBinder> getAppTasks(String callingPackage) {
9153        int callingUid = Binder.getCallingUid();
9154        long ident = Binder.clearCallingIdentity();
9155
9156        synchronized(this) {
9157            ArrayList<IBinder> list = new ArrayList<IBinder>();
9158            try {
9159                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9160
9161                final int N = mRecentTasks.size();
9162                for (int i = 0; i < N; i++) {
9163                    TaskRecord tr = mRecentTasks.get(i);
9164                    // Skip tasks that do not match the caller.  We don't need to verify
9165                    // callingPackage, because we are also limiting to callingUid and know
9166                    // that will limit to the correct security sandbox.
9167                    if (tr.effectiveUid != callingUid) {
9168                        continue;
9169                    }
9170                    Intent intent = tr.getBaseIntent();
9171                    if (intent == null ||
9172                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9173                        continue;
9174                    }
9175                    ActivityManager.RecentTaskInfo taskInfo =
9176                            createRecentTaskInfoFromTaskRecord(tr);
9177                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9178                    list.add(taskImpl.asBinder());
9179                }
9180            } finally {
9181                Binder.restoreCallingIdentity(ident);
9182            }
9183            return list;
9184        }
9185    }
9186
9187    @Override
9188    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9189        final int callingUid = Binder.getCallingUid();
9190        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9191
9192        synchronized(this) {
9193            if (DEBUG_ALL) Slog.v(
9194                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9195
9196            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9197                    callingUid);
9198
9199            // TODO: Improve with MRU list from all ActivityStacks.
9200            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9201        }
9202
9203        return list;
9204    }
9205
9206    /**
9207     * Creates a new RecentTaskInfo from a TaskRecord.
9208     */
9209    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9210        // Update the task description to reflect any changes in the task stack
9211        tr.updateTaskDescription();
9212
9213        // Compose the recent task info
9214        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9215        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9216        rti.persistentId = tr.taskId;
9217        rti.baseIntent = new Intent(tr.getBaseIntent());
9218        rti.origActivity = tr.origActivity;
9219        rti.realActivity = tr.realActivity;
9220        rti.description = tr.lastDescription;
9221        rti.stackId = tr.getStackId();
9222        rti.userId = tr.userId;
9223        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9224        rti.firstActiveTime = tr.firstActiveTime;
9225        rti.lastActiveTime = tr.lastActiveTime;
9226        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9227        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9228        rti.numActivities = 0;
9229        if (tr.mBounds != null) {
9230            rti.bounds = new Rect(tr.mBounds);
9231        }
9232        rti.isDockable = tr.canGoInDockedStack();
9233        rti.resizeMode = tr.mResizeMode;
9234
9235        ActivityRecord base = null;
9236        ActivityRecord top = null;
9237        ActivityRecord tmp;
9238
9239        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9240            tmp = tr.mActivities.get(i);
9241            if (tmp.finishing) {
9242                continue;
9243            }
9244            base = tmp;
9245            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9246                top = base;
9247            }
9248            rti.numActivities++;
9249        }
9250
9251        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9252        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9253
9254        return rti;
9255    }
9256
9257    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9258        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9259                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9260        if (!allowed) {
9261            if (checkPermission(android.Manifest.permission.GET_TASKS,
9262                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9263                // Temporary compatibility: some existing apps on the system image may
9264                // still be requesting the old permission and not switched to the new
9265                // one; if so, we'll still allow them full access.  This means we need
9266                // to see if they are holding the old permission and are a system app.
9267                try {
9268                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9269                        allowed = true;
9270                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9271                                + " is using old GET_TASKS but privileged; allowing");
9272                    }
9273                } catch (RemoteException e) {
9274                }
9275            }
9276        }
9277        if (!allowed) {
9278            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9279                    + " does not hold REAL_GET_TASKS; limiting output");
9280        }
9281        return allowed;
9282    }
9283
9284    @Override
9285    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9286            int userId) {
9287        final int callingUid = Binder.getCallingUid();
9288        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9289                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9290
9291        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9292        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9293        synchronized (this) {
9294            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9295                    callingUid);
9296            final boolean detailed = checkCallingPermission(
9297                    android.Manifest.permission.GET_DETAILED_TASKS)
9298                    == PackageManager.PERMISSION_GRANTED;
9299
9300            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9301                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9302                return ParceledListSlice.emptyList();
9303            }
9304            mRecentTasks.loadUserRecentsLocked(userId);
9305
9306            final int recentsCount = mRecentTasks.size();
9307            ArrayList<ActivityManager.RecentTaskInfo> res =
9308                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9309
9310            final Set<Integer> includedUsers;
9311            if (includeProfiles) {
9312                includedUsers = mUserController.getProfileIds(userId);
9313            } else {
9314                includedUsers = new HashSet<>();
9315            }
9316            includedUsers.add(Integer.valueOf(userId));
9317
9318            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9319                TaskRecord tr = mRecentTasks.get(i);
9320                // Only add calling user or related users recent tasks
9321                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9322                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9323                    continue;
9324                }
9325
9326                if (tr.realActivitySuspended) {
9327                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9328                    continue;
9329                }
9330
9331                // Return the entry if desired by the caller.  We always return
9332                // the first entry, because callers always expect this to be the
9333                // foreground app.  We may filter others if the caller has
9334                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9335                // we should exclude the entry.
9336
9337                if (i == 0
9338                        || withExcluded
9339                        || (tr.intent == null)
9340                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9341                                == 0)) {
9342                    if (!allowed) {
9343                        // If the caller doesn't have the GET_TASKS permission, then only
9344                        // allow them to see a small subset of tasks -- their own and home.
9345                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9346                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9347                            continue;
9348                        }
9349                    }
9350                    final ActivityStack stack = tr.getStack();
9351                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9352                        if (stack != null && stack.isHomeOrRecentsStack()) {
9353                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9354                                    "Skipping, home or recents stack task: " + tr);
9355                            continue;
9356                        }
9357                    }
9358                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9359                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9360                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9361                                    "Skipping, top task in docked stack: " + tr);
9362                            continue;
9363                        }
9364                    }
9365                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9366                        if (stack != null && stack.isPinnedStack()) {
9367                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9368                                    "Skipping, pinned stack task: " + tr);
9369                            continue;
9370                        }
9371                    }
9372                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9373                        // Don't include auto remove tasks that are finished or finishing.
9374                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9375                                "Skipping, auto-remove without activity: " + tr);
9376                        continue;
9377                    }
9378                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9379                            && !tr.isAvailable) {
9380                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9381                                "Skipping, unavail real act: " + tr);
9382                        continue;
9383                    }
9384
9385                    if (!tr.mUserSetupComplete) {
9386                        // Don't include task launched while user is not done setting-up.
9387                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9388                                "Skipping, user setup not complete: " + tr);
9389                        continue;
9390                    }
9391
9392                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9393                    if (!detailed) {
9394                        rti.baseIntent.replaceExtras((Bundle)null);
9395                    }
9396
9397                    res.add(rti);
9398                    maxNum--;
9399                }
9400            }
9401            return new ParceledListSlice<>(res);
9402        }
9403    }
9404
9405    @Override
9406    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9407        synchronized (this) {
9408            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9409                    "getTaskThumbnail()");
9410            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9411                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9412            if (tr != null) {
9413                return tr.getTaskThumbnailLocked();
9414            }
9415        }
9416        return null;
9417    }
9418
9419    @Override
9420    public int addAppTask(IBinder activityToken, Intent intent,
9421            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9422        final int callingUid = Binder.getCallingUid();
9423        final long callingIdent = Binder.clearCallingIdentity();
9424
9425        try {
9426            synchronized (this) {
9427                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9428                if (r == null) {
9429                    throw new IllegalArgumentException("Activity does not exist; token="
9430                            + activityToken);
9431                }
9432                ComponentName comp = intent.getComponent();
9433                if (comp == null) {
9434                    throw new IllegalArgumentException("Intent " + intent
9435                            + " must specify explicit component");
9436                }
9437                if (thumbnail.getWidth() != mThumbnailWidth
9438                        || thumbnail.getHeight() != mThumbnailHeight) {
9439                    throw new IllegalArgumentException("Bad thumbnail size: got "
9440                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9441                            + mThumbnailWidth + "x" + mThumbnailHeight);
9442                }
9443                if (intent.getSelector() != null) {
9444                    intent.setSelector(null);
9445                }
9446                if (intent.getSourceBounds() != null) {
9447                    intent.setSourceBounds(null);
9448                }
9449                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9450                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9451                        // The caller has added this as an auto-remove task...  that makes no
9452                        // sense, so turn off auto-remove.
9453                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9454                    }
9455                }
9456                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9457                    mLastAddedTaskActivity = null;
9458                }
9459                ActivityInfo ainfo = mLastAddedTaskActivity;
9460                if (ainfo == null) {
9461                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9462                            comp, 0, UserHandle.getUserId(callingUid));
9463                    if (ainfo.applicationInfo.uid != callingUid) {
9464                        throw new SecurityException(
9465                                "Can't add task for another application: target uid="
9466                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9467                    }
9468                }
9469
9470                TaskRecord task = new TaskRecord(this,
9471                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9472                        ainfo, intent, description, new TaskThumbnailInfo());
9473
9474                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9475                if (trimIdx >= 0) {
9476                    // If this would have caused a trim, then we'll abort because that
9477                    // means it would be added at the end of the list but then just removed.
9478                    return INVALID_TASK_ID;
9479                }
9480
9481                final int N = mRecentTasks.size();
9482                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9483                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9484                    tr.removedFromRecents();
9485                }
9486
9487                task.inRecents = true;
9488                mRecentTasks.add(task);
9489                r.getStack().addTask(task, false, "addAppTask");
9490
9491                task.setLastThumbnailLocked(thumbnail);
9492                task.freeLastThumbnail();
9493                return task.taskId;
9494            }
9495        } finally {
9496            Binder.restoreCallingIdentity(callingIdent);
9497        }
9498    }
9499
9500    @Override
9501    public Point getAppTaskThumbnailSize() {
9502        synchronized (this) {
9503            return new Point(mThumbnailWidth,  mThumbnailHeight);
9504        }
9505    }
9506
9507    @Override
9508    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9509        synchronized (this) {
9510            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9511            if (r != null) {
9512                r.setTaskDescription(td);
9513                r.task.updateTaskDescription();
9514                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9515            }
9516        }
9517    }
9518
9519    @Override
9520    public void setTaskResizeable(int taskId, int resizeableMode) {
9521        synchronized (this) {
9522            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9523                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9524            if (task == null) {
9525                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9526                return;
9527            }
9528            if (task.mResizeMode != resizeableMode) {
9529                task.mResizeMode = resizeableMode;
9530                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9531                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9532                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9533            }
9534        }
9535    }
9536
9537    @Override
9538    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9539        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9540        long ident = Binder.clearCallingIdentity();
9541        try {
9542            synchronized (this) {
9543                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9544                if (task == null) {
9545                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9546                    return;
9547                }
9548                // Place the task in the right stack if it isn't there already based on
9549                // the requested bounds.
9550                // The stack transition logic is:
9551                // - a null bounds on a freeform task moves that task to fullscreen
9552                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9553                //   that task to freeform
9554                // - otherwise the task is not moved
9555                int stackId = task.getStackId();
9556                if (!StackId.isTaskResizeAllowed(stackId)) {
9557                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9558                }
9559                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9560                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9561                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9562                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9563                }
9564                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9565                if (stackId != task.getStackId()) {
9566                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9567                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9568                    preserveWindow = false;
9569                }
9570
9571                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9572                        false /* deferResume */);
9573            }
9574        } finally {
9575            Binder.restoreCallingIdentity(ident);
9576        }
9577    }
9578
9579    @Override
9580    public Rect getTaskBounds(int taskId) {
9581        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9582        long ident = Binder.clearCallingIdentity();
9583        Rect rect = new Rect();
9584        try {
9585            synchronized (this) {
9586                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9587                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9588                if (task == null) {
9589                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9590                    return rect;
9591                }
9592                if (task.getStack() != null) {
9593                    // Return the bounds from window manager since it will be adjusted for various
9594                    // things like the presense of a docked stack for tasks that aren't resizeable.
9595                    mWindowManager.getTaskBounds(task.taskId, rect);
9596                } else {
9597                    // Task isn't in window manager yet since it isn't associated with a stack.
9598                    // Return the persist value from activity manager
9599                    if (task.mBounds != null) {
9600                        rect.set(task.mBounds);
9601                    } else if (task.mLastNonFullscreenBounds != null) {
9602                        rect.set(task.mLastNonFullscreenBounds);
9603                    }
9604                }
9605            }
9606        } finally {
9607            Binder.restoreCallingIdentity(ident);
9608        }
9609        return rect;
9610    }
9611
9612    @Override
9613    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9614        if (userId != UserHandle.getCallingUserId()) {
9615            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9616                    "getTaskDescriptionIcon");
9617        }
9618        final File passedIconFile = new File(filePath);
9619        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9620                passedIconFile.getName());
9621        if (!legitIconFile.getPath().equals(filePath)
9622                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9623            throw new IllegalArgumentException("Bad file path: " + filePath
9624                    + " passed for userId " + userId);
9625        }
9626        return mRecentTasks.getTaskDescriptionIcon(filePath);
9627    }
9628
9629    @Override
9630    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9631            throws RemoteException {
9632        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9633        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9634                activityOptions.getCustomInPlaceResId() == 0) {
9635            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9636                    "with valid animation");
9637        }
9638        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9639        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9640                activityOptions.getCustomInPlaceResId());
9641        mWindowManager.executeAppTransition();
9642    }
9643
9644    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9645        // Remove all tasks with activities in the specified package from the list of recent tasks
9646        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9647            TaskRecord tr = mRecentTasks.get(i);
9648            if (tr.userId != userId) continue;
9649
9650            ComponentName cn = tr.intent.getComponent();
9651            if (cn != null && cn.getPackageName().equals(packageName)) {
9652                // If the package name matches, remove the task.
9653                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9654            }
9655        }
9656    }
9657
9658    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9659            int userId) {
9660
9661        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9662            TaskRecord tr = mRecentTasks.get(i);
9663            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9664                continue;
9665            }
9666
9667            ComponentName cn = tr.intent.getComponent();
9668            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9669                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9670            if (sameComponent) {
9671                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9672            }
9673        }
9674    }
9675
9676    @Override
9677    public void removeStack(int stackId) {
9678        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9679        if (StackId.isHomeOrRecentsStack(stackId)) {
9680            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
9681        }
9682
9683        synchronized (this) {
9684            final long ident = Binder.clearCallingIdentity();
9685            try {
9686                mStackSupervisor.removeStackLocked(stackId);
9687            } finally {
9688                Binder.restoreCallingIdentity(ident);
9689            }
9690        }
9691    }
9692
9693    @Override
9694    public void moveStackToDisplay(int stackId, int displayId) {
9695        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
9696
9697        synchronized (this) {
9698            final long ident = Binder.clearCallingIdentity();
9699            try {
9700                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
9701                        + " to displayId=" + displayId);
9702                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId);
9703            } finally {
9704                Binder.restoreCallingIdentity(ident);
9705            }
9706        }
9707    }
9708
9709    @Override
9710    public boolean removeTask(int taskId) {
9711        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9712        synchronized (this) {
9713            final long ident = Binder.clearCallingIdentity();
9714            try {
9715                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9716            } finally {
9717                Binder.restoreCallingIdentity(ident);
9718            }
9719        }
9720    }
9721
9722    /**
9723     * TODO: Add mController hook
9724     */
9725    @Override
9726    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9727        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9728
9729        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9730        synchronized(this) {
9731            moveTaskToFrontLocked(taskId, flags, bOptions);
9732        }
9733    }
9734
9735    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9736        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9737
9738        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9739                Binder.getCallingUid(), -1, -1, "Task to front")) {
9740            ActivityOptions.abort(options);
9741            return;
9742        }
9743        final long origId = Binder.clearCallingIdentity();
9744        try {
9745            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9746            if (task == null) {
9747                Slog.d(TAG, "Could not find task for id: "+ taskId);
9748                return;
9749            }
9750            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9751                mStackSupervisor.showLockTaskToast();
9752                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9753                return;
9754            }
9755            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9756            if (prev != null && prev.isRecentsActivity()) {
9757                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9758            }
9759            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9760                    false /* forceNonResizable */);
9761        } finally {
9762            Binder.restoreCallingIdentity(origId);
9763        }
9764        ActivityOptions.abort(options);
9765    }
9766
9767    /**
9768     * Moves an activity, and all of the other activities within the same task, to the bottom
9769     * of the history stack.  The activity's order within the task is unchanged.
9770     *
9771     * @param token A reference to the activity we wish to move
9772     * @param nonRoot If false then this only works if the activity is the root
9773     *                of a task; if true it will work for any activity in a task.
9774     * @return Returns true if the move completed, false if not.
9775     */
9776    @Override
9777    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9778        enforceNotIsolatedCaller("moveActivityTaskToBack");
9779        synchronized(this) {
9780            final long origId = Binder.clearCallingIdentity();
9781            try {
9782                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9783                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9784                if (task != null) {
9785                    if (mStackSupervisor.isLockedTask(task)) {
9786                        mStackSupervisor.showLockTaskToast();
9787                        return false;
9788                    }
9789                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9790                }
9791            } finally {
9792                Binder.restoreCallingIdentity(origId);
9793            }
9794        }
9795        return false;
9796    }
9797
9798    @Override
9799    public void moveTaskBackwards(int task) {
9800        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9801                "moveTaskBackwards()");
9802
9803        synchronized(this) {
9804            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9805                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9806                return;
9807            }
9808            final long origId = Binder.clearCallingIdentity();
9809            moveTaskBackwardsLocked(task);
9810            Binder.restoreCallingIdentity(origId);
9811        }
9812    }
9813
9814    private final void moveTaskBackwardsLocked(int task) {
9815        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9816    }
9817
9818    @Override
9819    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9820            IActivityContainerCallback callback) throws RemoteException {
9821        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9822        synchronized (this) {
9823            if (parentActivityToken == null) {
9824                throw new IllegalArgumentException("parent token must not be null");
9825            }
9826            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9827            if (r == null) {
9828                return null;
9829            }
9830            if (callback == null) {
9831                throw new IllegalArgumentException("callback must not be null");
9832            }
9833            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9834        }
9835    }
9836
9837    @Override
9838    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9839        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9840        synchronized (this) {
9841            final int stackId = mStackSupervisor.getNextStackId();
9842            final ActivityStack stack =
9843                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9844            if (stack == null) {
9845                return null;
9846            }
9847            return stack.mActivityContainer;
9848        }
9849    }
9850
9851    @Override
9852    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9853        synchronized (this) {
9854            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9855            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9856                return stack.mActivityContainer.getDisplayId();
9857            }
9858            return DEFAULT_DISPLAY;
9859        }
9860    }
9861
9862    @Override
9863    public int getActivityStackId(IBinder token) throws RemoteException {
9864        synchronized (this) {
9865            ActivityStack stack = ActivityRecord.getStackLocked(token);
9866            if (stack == null) {
9867                return INVALID_STACK_ID;
9868            }
9869            return stack.mStackId;
9870        }
9871    }
9872
9873    @Override
9874    public void exitFreeformMode(IBinder token) throws RemoteException {
9875        synchronized (this) {
9876            long ident = Binder.clearCallingIdentity();
9877            try {
9878                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9879                if (r == null) {
9880                    throw new IllegalArgumentException(
9881                            "exitFreeformMode: No activity record matching token=" + token);
9882                }
9883                final ActivityStack stack = r.getStackLocked(token);
9884                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9885                    throw new IllegalStateException(
9886                            "exitFreeformMode: You can only go fullscreen from freeform.");
9887                }
9888                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9889                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9890                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9891            } finally {
9892                Binder.restoreCallingIdentity(ident);
9893            }
9894        }
9895    }
9896
9897    @Override
9898    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9899        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9900        if (StackId.isHomeOrRecentsStack(stackId)) {
9901            throw new IllegalArgumentException(
9902                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
9903        }
9904        synchronized (this) {
9905            long ident = Binder.clearCallingIdentity();
9906            try {
9907                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9908                        + " to stackId=" + stackId + " toTop=" + toTop);
9909                if (stackId == DOCKED_STACK_ID) {
9910                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9911                            null /* initialBounds */);
9912                }
9913                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9914                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9915                if (result && stackId == DOCKED_STACK_ID) {
9916                    // If task moved to docked stack - show recents if needed.
9917                    mWindowManager.showRecentApps(false /* fromHome */);
9918                }
9919            } finally {
9920                Binder.restoreCallingIdentity(ident);
9921            }
9922        }
9923    }
9924
9925    @Override
9926    public void swapDockedAndFullscreenStack() throws RemoteException {
9927        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9928        synchronized (this) {
9929            long ident = Binder.clearCallingIdentity();
9930            try {
9931                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9932                        FULLSCREEN_WORKSPACE_STACK_ID);
9933                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9934                        : null;
9935                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9936                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9937                        : null;
9938                if (topTask == null || tasks == null || tasks.size() == 0) {
9939                    Slog.w(TAG,
9940                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9941                    return;
9942                }
9943
9944                // TODO: App transition
9945                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9946
9947                // Defer the resume so resume/pausing while moving stacks is dangerous.
9948                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9949                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9950                        ANIMATE, true /* deferResume */);
9951                final int size = tasks.size();
9952                for (int i = 0; i < size; i++) {
9953                    final int id = tasks.get(i).taskId;
9954                    if (id == topTask.taskId) {
9955                        continue;
9956                    }
9957                    mStackSupervisor.moveTaskToStackLocked(id,
9958                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9959                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9960                }
9961
9962                // Because we deferred the resume, to avoid conflicts with stack switches while
9963                // resuming, we need to do it after all the tasks are moved.
9964                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9965                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9966
9967                mWindowManager.executeAppTransition();
9968            } finally {
9969                Binder.restoreCallingIdentity(ident);
9970            }
9971        }
9972    }
9973
9974    /**
9975     * Moves the input task to the docked stack.
9976     *
9977     * @param taskId Id of task to move.
9978     * @param createMode The mode the docked stack should be created in if it doesn't exist
9979     *                   already. See
9980     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9981     *                   and
9982     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9983     * @param toTop If the task and stack should be moved to the top.
9984     * @param animate Whether we should play an animation for the moving the task
9985     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9986     *                      docked stack. Pass {@code null} to use default bounds.
9987     */
9988    @Override
9989    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9990            Rect initialBounds, boolean moveHomeStackFront) {
9991        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9992        synchronized (this) {
9993            long ident = Binder.clearCallingIdentity();
9994            try {
9995                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9996                        + " to createMode=" + createMode + " toTop=" + toTop);
9997                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9998                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9999                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10000                        animate, DEFER_RESUME);
10001                if (moved) {
10002                    if (moveHomeStackFront) {
10003                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10004                    }
10005                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10006                }
10007                return moved;
10008            } finally {
10009                Binder.restoreCallingIdentity(ident);
10010            }
10011        }
10012    }
10013
10014    /**
10015     * Moves the top activity in the input stackId to the pinned stack.
10016     *
10017     * @param stackId Id of stack to move the top activity to pinned stack.
10018     * @param bounds Bounds to use for pinned stack.
10019     *
10020     * @return True if the top activity of the input stack was successfully moved to the pinned
10021     *          stack.
10022     */
10023    @Override
10024    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10025        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10026        synchronized (this) {
10027            if (!mSupportsPictureInPicture) {
10028                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10029                        + "Device doesn't support picture-in-pciture mode");
10030            }
10031
10032            long ident = Binder.clearCallingIdentity();
10033            try {
10034                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10035            } finally {
10036                Binder.restoreCallingIdentity(ident);
10037            }
10038        }
10039    }
10040
10041    @Override
10042    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10043            boolean preserveWindows, boolean animate, int animationDuration) {
10044        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10045        long ident = Binder.clearCallingIdentity();
10046        try {
10047            synchronized (this) {
10048                if (animate) {
10049                    if (stackId == PINNED_STACK_ID) {
10050                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10051                    } else {
10052                        throw new IllegalArgumentException("Stack: " + stackId
10053                                + " doesn't support animated resize.");
10054                    }
10055                } else {
10056                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10057                            null /* tempTaskInsetBounds */, preserveWindows,
10058                            allowResizeInDockedMode, !DEFER_RESUME);
10059                }
10060            }
10061        } finally {
10062            Binder.restoreCallingIdentity(ident);
10063        }
10064    }
10065
10066    @Override
10067    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10068            Rect tempDockedTaskInsetBounds,
10069            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10070        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10071                "resizeDockedStack()");
10072        long ident = Binder.clearCallingIdentity();
10073        try {
10074            synchronized (this) {
10075                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10076                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10077                        PRESERVE_WINDOWS);
10078            }
10079        } finally {
10080            Binder.restoreCallingIdentity(ident);
10081        }
10082    }
10083
10084    @Override
10085    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10086        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10087                "resizePinnedStack()");
10088        final long ident = Binder.clearCallingIdentity();
10089        try {
10090            synchronized (this) {
10091                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10092            }
10093        } finally {
10094            Binder.restoreCallingIdentity(ident);
10095        }
10096    }
10097
10098    /**
10099     * Try to place task to provided position. The final position might be different depending on
10100     * current user and stacks state. The task will be moved to target stack if it's currently in
10101     * different stack.
10102     */
10103    @Override
10104    public void positionTaskInStack(int taskId, int stackId, int position) {
10105        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10106        if (StackId.isHomeOrRecentsStack(stackId)) {
10107            throw new IllegalArgumentException(
10108                    "positionTaskInStack: Attempt to change the position of task "
10109                    + taskId + " in/to home/recents stack");
10110        }
10111        synchronized (this) {
10112            long ident = Binder.clearCallingIdentity();
10113            try {
10114                if (DEBUG_STACK) Slog.d(TAG_STACK,
10115                        "positionTaskInStack: positioning task=" + taskId
10116                        + " in stackId=" + stackId + " at position=" + position);
10117                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10118            } finally {
10119                Binder.restoreCallingIdentity(ident);
10120            }
10121        }
10122    }
10123
10124    @Override
10125    public List<StackInfo> getAllStackInfos() {
10126        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10127        long ident = Binder.clearCallingIdentity();
10128        try {
10129            synchronized (this) {
10130                return mStackSupervisor.getAllStackInfosLocked();
10131            }
10132        } finally {
10133            Binder.restoreCallingIdentity(ident);
10134        }
10135    }
10136
10137    @Override
10138    public StackInfo getStackInfo(int stackId) {
10139        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10140        long ident = Binder.clearCallingIdentity();
10141        try {
10142            synchronized (this) {
10143                return mStackSupervisor.getStackInfoLocked(stackId);
10144            }
10145        } finally {
10146            Binder.restoreCallingIdentity(ident);
10147        }
10148    }
10149
10150    @Override
10151    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10152        synchronized(this) {
10153            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10154        }
10155    }
10156
10157    @Override
10158    public void updateDeviceOwner(String packageName) {
10159        final int callingUid = Binder.getCallingUid();
10160        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10161            throw new SecurityException("updateDeviceOwner called from non-system process");
10162        }
10163        synchronized (this) {
10164            mDeviceOwnerName = packageName;
10165        }
10166    }
10167
10168    @Override
10169    public void updateLockTaskPackages(int userId, String[] packages) {
10170        final int callingUid = Binder.getCallingUid();
10171        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10172            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10173                    "updateLockTaskPackages()");
10174        }
10175        synchronized (this) {
10176            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10177                    Arrays.toString(packages));
10178            mLockTaskPackages.put(userId, packages);
10179            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10180        }
10181    }
10182
10183
10184    void startLockTaskModeLocked(TaskRecord task) {
10185        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10186        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10187            return;
10188        }
10189
10190        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10191        // is initiated by system after the pinning request was shown and locked mode is initiated
10192        // by an authorized app directly
10193        final int callingUid = Binder.getCallingUid();
10194        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10195        long ident = Binder.clearCallingIdentity();
10196        try {
10197            if (!isSystemInitiated) {
10198                task.mLockTaskUid = callingUid;
10199                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10200                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10201                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10202                    StatusBarManagerInternal statusBarManager =
10203                            LocalServices.getService(StatusBarManagerInternal.class);
10204                    if (statusBarManager != null) {
10205                        statusBarManager.showScreenPinningRequest(task.taskId);
10206                    }
10207                    return;
10208                }
10209
10210                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10211                if (stack == null || task != stack.topTask()) {
10212                    throw new IllegalArgumentException("Invalid task, not in foreground");
10213                }
10214            }
10215            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10216                    "Locking fully");
10217            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10218                    ActivityManager.LOCK_TASK_MODE_PINNED :
10219                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10220                    "startLockTask", true);
10221        } finally {
10222            Binder.restoreCallingIdentity(ident);
10223        }
10224    }
10225
10226    @Override
10227    public void startLockTaskModeById(int taskId) {
10228        synchronized (this) {
10229            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10230            if (task != null) {
10231                startLockTaskModeLocked(task);
10232            }
10233        }
10234    }
10235
10236    @Override
10237    public void startLockTaskModeByToken(IBinder token) {
10238        synchronized (this) {
10239            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10240            if (r == null) {
10241                return;
10242            }
10243            final TaskRecord task = r.task;
10244            if (task != null) {
10245                startLockTaskModeLocked(task);
10246            }
10247        }
10248    }
10249
10250    @Override
10251    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10252        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10253        // This makes inner call to look as if it was initiated by system.
10254        long ident = Binder.clearCallingIdentity();
10255        try {
10256            synchronized (this) {
10257                startLockTaskModeById(taskId);
10258            }
10259        } finally {
10260            Binder.restoreCallingIdentity(ident);
10261        }
10262    }
10263
10264    @Override
10265    public void stopLockTaskMode() {
10266        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10267        if (lockTask == null) {
10268            // Our work here is done.
10269            return;
10270        }
10271
10272        final int callingUid = Binder.getCallingUid();
10273        final int lockTaskUid = lockTask.mLockTaskUid;
10274        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10275        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10276            // Done.
10277            return;
10278        } else {
10279            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10280            // It is possible lockTaskMode was started by the system process because
10281            // android:lockTaskMode is set to a locking value in the application manifest
10282            // instead of the app calling startLockTaskMode. In this case
10283            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10284            // {@link TaskRecord.effectiveUid} instead. Also caller with
10285            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10286            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10287                    && callingUid != lockTaskUid
10288                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10289                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10290                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10291            }
10292        }
10293        long ident = Binder.clearCallingIdentity();
10294        try {
10295            Log.d(TAG, "stopLockTaskMode");
10296            // Stop lock task
10297            synchronized (this) {
10298                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10299                        "stopLockTask", true);
10300            }
10301            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10302            if (tm != null) {
10303                tm.showInCallScreen(false);
10304            }
10305        } finally {
10306            Binder.restoreCallingIdentity(ident);
10307        }
10308    }
10309
10310    /**
10311     * This API should be called by SystemUI only when user perform certain action to dismiss
10312     * lock task mode. We should only dismiss pinned lock task mode in this case.
10313     */
10314    @Override
10315    public void stopSystemLockTaskMode() throws RemoteException {
10316        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10317            stopLockTaskMode();
10318        } else {
10319            mStackSupervisor.showLockTaskToast();
10320        }
10321    }
10322
10323    @Override
10324    public boolean isInLockTaskMode() {
10325        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10326    }
10327
10328    @Override
10329    public int getLockTaskModeState() {
10330        synchronized (this) {
10331            return mStackSupervisor.getLockTaskModeState();
10332        }
10333    }
10334
10335    @Override
10336    public void showLockTaskEscapeMessage(IBinder token) {
10337        synchronized (this) {
10338            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10339            if (r == null) {
10340                return;
10341            }
10342            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10343        }
10344    }
10345
10346    // =========================================================
10347    // CONTENT PROVIDERS
10348    // =========================================================
10349
10350    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10351        List<ProviderInfo> providers = null;
10352        try {
10353            providers = AppGlobals.getPackageManager()
10354                    .queryContentProviders(app.processName, app.uid,
10355                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10356                                    | MATCH_DEBUG_TRIAGED_MISSING)
10357                    .getList();
10358        } catch (RemoteException ex) {
10359        }
10360        if (DEBUG_MU) Slog.v(TAG_MU,
10361                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10362        int userId = app.userId;
10363        if (providers != null) {
10364            int N = providers.size();
10365            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10366            for (int i=0; i<N; i++) {
10367                // TODO: keep logic in sync with installEncryptionUnawareProviders
10368                ProviderInfo cpi =
10369                    (ProviderInfo)providers.get(i);
10370                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10371                        cpi.name, cpi.flags);
10372                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10373                    // This is a singleton provider, but a user besides the
10374                    // default user is asking to initialize a process it runs
10375                    // in...  well, no, it doesn't actually run in this process,
10376                    // it runs in the process of the default user.  Get rid of it.
10377                    providers.remove(i);
10378                    N--;
10379                    i--;
10380                    continue;
10381                }
10382
10383                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10384                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10385                if (cpr == null) {
10386                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10387                    mProviderMap.putProviderByClass(comp, cpr);
10388                }
10389                if (DEBUG_MU) Slog.v(TAG_MU,
10390                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10391                app.pubProviders.put(cpi.name, cpr);
10392                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10393                    // Don't add this if it is a platform component that is marked
10394                    // to run in multiple processes, because this is actually
10395                    // part of the framework so doesn't make sense to track as a
10396                    // separate apk in the process.
10397                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10398                            mProcessStats);
10399                }
10400                notifyPackageUse(cpi.applicationInfo.packageName,
10401                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10402            }
10403        }
10404        return providers;
10405    }
10406
10407    /**
10408     * Check if the calling UID has a possible chance at accessing the provider
10409     * at the given authority and user.
10410     */
10411    public String checkContentProviderAccess(String authority, int userId) {
10412        if (userId == UserHandle.USER_ALL) {
10413            mContext.enforceCallingOrSelfPermission(
10414                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10415            userId = UserHandle.getCallingUserId();
10416        }
10417
10418        ProviderInfo cpi = null;
10419        try {
10420            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10421                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10422                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10423                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10424                    userId);
10425        } catch (RemoteException ignored) {
10426        }
10427        if (cpi == null) {
10428            // TODO: make this an outright failure in a future platform release;
10429            // until then anonymous content notifications are unprotected
10430            //return "Failed to find provider " + authority + " for user " + userId;
10431            return null;
10432        }
10433
10434        ProcessRecord r = null;
10435        synchronized (mPidsSelfLocked) {
10436            r = mPidsSelfLocked.get(Binder.getCallingPid());
10437        }
10438        if (r == null) {
10439            return "Failed to find PID " + Binder.getCallingPid();
10440        }
10441
10442        synchronized (this) {
10443            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10444        }
10445    }
10446
10447    /**
10448     * Check if {@link ProcessRecord} has a possible chance at accessing the
10449     * given {@link ProviderInfo}. Final permission checking is always done
10450     * in {@link ContentProvider}.
10451     */
10452    private final String checkContentProviderPermissionLocked(
10453            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10454        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10455        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10456        boolean checkedGrants = false;
10457        if (checkUser) {
10458            // Looking for cross-user grants before enforcing the typical cross-users permissions
10459            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10460            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10461                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10462                    return null;
10463                }
10464                checkedGrants = true;
10465            }
10466            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10467                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10468            if (userId != tmpTargetUserId) {
10469                // When we actually went to determine the final targer user ID, this ended
10470                // up different than our initial check for the authority.  This is because
10471                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10472                // SELF.  So we need to re-check the grants again.
10473                checkedGrants = false;
10474            }
10475        }
10476        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10477                cpi.applicationInfo.uid, cpi.exported)
10478                == PackageManager.PERMISSION_GRANTED) {
10479            return null;
10480        }
10481        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10482                cpi.applicationInfo.uid, cpi.exported)
10483                == PackageManager.PERMISSION_GRANTED) {
10484            return null;
10485        }
10486
10487        PathPermission[] pps = cpi.pathPermissions;
10488        if (pps != null) {
10489            int i = pps.length;
10490            while (i > 0) {
10491                i--;
10492                PathPermission pp = pps[i];
10493                String pprperm = pp.getReadPermission();
10494                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10495                        cpi.applicationInfo.uid, cpi.exported)
10496                        == PackageManager.PERMISSION_GRANTED) {
10497                    return null;
10498                }
10499                String ppwperm = pp.getWritePermission();
10500                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10501                        cpi.applicationInfo.uid, cpi.exported)
10502                        == PackageManager.PERMISSION_GRANTED) {
10503                    return null;
10504                }
10505            }
10506        }
10507        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10508            return null;
10509        }
10510
10511        String msg;
10512        if (!cpi.exported) {
10513            msg = "Permission Denial: opening provider " + cpi.name
10514                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10515                    + ", uid=" + callingUid + ") that is not exported from uid "
10516                    + cpi.applicationInfo.uid;
10517        } else {
10518            msg = "Permission Denial: opening provider " + cpi.name
10519                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10520                    + ", uid=" + callingUid + ") requires "
10521                    + cpi.readPermission + " or " + cpi.writePermission;
10522        }
10523        Slog.w(TAG, msg);
10524        return msg;
10525    }
10526
10527    /**
10528     * Returns if the ContentProvider has granted a uri to callingUid
10529     */
10530    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10531        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10532        if (perms != null) {
10533            for (int i=perms.size()-1; i>=0; i--) {
10534                GrantUri grantUri = perms.keyAt(i);
10535                if (grantUri.sourceUserId == userId || !checkUser) {
10536                    if (matchesProvider(grantUri.uri, cpi)) {
10537                        return true;
10538                    }
10539                }
10540            }
10541        }
10542        return false;
10543    }
10544
10545    /**
10546     * Returns true if the uri authority is one of the authorities specified in the provider.
10547     */
10548    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10549        String uriAuth = uri.getAuthority();
10550        String cpiAuth = cpi.authority;
10551        if (cpiAuth.indexOf(';') == -1) {
10552            return cpiAuth.equals(uriAuth);
10553        }
10554        String[] cpiAuths = cpiAuth.split(";");
10555        int length = cpiAuths.length;
10556        for (int i = 0; i < length; i++) {
10557            if (cpiAuths[i].equals(uriAuth)) return true;
10558        }
10559        return false;
10560    }
10561
10562    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10563            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10564        if (r != null) {
10565            for (int i=0; i<r.conProviders.size(); i++) {
10566                ContentProviderConnection conn = r.conProviders.get(i);
10567                if (conn.provider == cpr) {
10568                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10569                            "Adding provider requested by "
10570                            + r.processName + " from process "
10571                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10572                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10573                    if (stable) {
10574                        conn.stableCount++;
10575                        conn.numStableIncs++;
10576                    } else {
10577                        conn.unstableCount++;
10578                        conn.numUnstableIncs++;
10579                    }
10580                    return conn;
10581                }
10582            }
10583            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10584            if (stable) {
10585                conn.stableCount = 1;
10586                conn.numStableIncs = 1;
10587            } else {
10588                conn.unstableCount = 1;
10589                conn.numUnstableIncs = 1;
10590            }
10591            cpr.connections.add(conn);
10592            r.conProviders.add(conn);
10593            startAssociationLocked(r.uid, r.processName, r.curProcState,
10594                    cpr.uid, cpr.name, cpr.info.processName);
10595            return conn;
10596        }
10597        cpr.addExternalProcessHandleLocked(externalProcessToken);
10598        return null;
10599    }
10600
10601    boolean decProviderCountLocked(ContentProviderConnection conn,
10602            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10603        if (conn != null) {
10604            cpr = conn.provider;
10605            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10606                    "Removing provider requested by "
10607                    + conn.client.processName + " from process "
10608                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10609                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10610            if (stable) {
10611                conn.stableCount--;
10612            } else {
10613                conn.unstableCount--;
10614            }
10615            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10616                cpr.connections.remove(conn);
10617                conn.client.conProviders.remove(conn);
10618                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10619                    // The client is more important than last activity -- note the time this
10620                    // is happening, so we keep the old provider process around a bit as last
10621                    // activity to avoid thrashing it.
10622                    if (cpr.proc != null) {
10623                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10624                    }
10625                }
10626                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10627                return true;
10628            }
10629            return false;
10630        }
10631        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10632        return false;
10633    }
10634
10635    private void checkTime(long startTime, String where) {
10636        long now = SystemClock.uptimeMillis();
10637        if ((now-startTime) > 50) {
10638            // If we are taking more than 50ms, log about it.
10639            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10640        }
10641    }
10642
10643    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10644            PROC_SPACE_TERM,
10645            PROC_SPACE_TERM|PROC_PARENS,
10646            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10647    };
10648
10649    private final long[] mProcessStateStatsLongs = new long[1];
10650
10651    boolean isProcessAliveLocked(ProcessRecord proc) {
10652        if (proc.procStatFile == null) {
10653            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10654        }
10655        mProcessStateStatsLongs[0] = 0;
10656        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10657                mProcessStateStatsLongs, null)) {
10658            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10659            return false;
10660        }
10661        final long state = mProcessStateStatsLongs[0];
10662        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10663                + (char)state);
10664        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10665    }
10666
10667    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10668            String name, IBinder token, boolean stable, int userId) {
10669        ContentProviderRecord cpr;
10670        ContentProviderConnection conn = null;
10671        ProviderInfo cpi = null;
10672
10673        synchronized(this) {
10674            long startTime = SystemClock.uptimeMillis();
10675
10676            ProcessRecord r = null;
10677            if (caller != null) {
10678                r = getRecordForAppLocked(caller);
10679                if (r == null) {
10680                    throw new SecurityException(
10681                            "Unable to find app for caller " + caller
10682                          + " (pid=" + Binder.getCallingPid()
10683                          + ") when getting content provider " + name);
10684                }
10685            }
10686
10687            boolean checkCrossUser = true;
10688
10689            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10690
10691            // First check if this content provider has been published...
10692            cpr = mProviderMap.getProviderByName(name, userId);
10693            // If that didn't work, check if it exists for user 0 and then
10694            // verify that it's a singleton provider before using it.
10695            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10696                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10697                if (cpr != null) {
10698                    cpi = cpr.info;
10699                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10700                            cpi.name, cpi.flags)
10701                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10702                        userId = UserHandle.USER_SYSTEM;
10703                        checkCrossUser = false;
10704                    } else {
10705                        cpr = null;
10706                        cpi = null;
10707                    }
10708                }
10709            }
10710
10711            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10712            if (providerRunning) {
10713                cpi = cpr.info;
10714                String msg;
10715                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10716                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10717                        != null) {
10718                    throw new SecurityException(msg);
10719                }
10720                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10721
10722                if (r != null && cpr.canRunHere(r)) {
10723                    // This provider has been published or is in the process
10724                    // of being published...  but it is also allowed to run
10725                    // in the caller's process, so don't make a connection
10726                    // and just let the caller instantiate its own instance.
10727                    ContentProviderHolder holder = cpr.newHolder(null);
10728                    // don't give caller the provider object, it needs
10729                    // to make its own.
10730                    holder.provider = null;
10731                    return holder;
10732                }
10733
10734                final long origId = Binder.clearCallingIdentity();
10735
10736                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10737
10738                // In this case the provider instance already exists, so we can
10739                // return it right away.
10740                conn = incProviderCountLocked(r, cpr, token, stable);
10741                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10742                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10743                        // If this is a perceptible app accessing the provider,
10744                        // make sure to count it as being accessed and thus
10745                        // back up on the LRU list.  This is good because
10746                        // content providers are often expensive to start.
10747                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10748                        updateLruProcessLocked(cpr.proc, false, null);
10749                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10750                    }
10751                }
10752
10753                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10754                final int verifiedAdj = cpr.proc.verifiedAdj;
10755                boolean success = updateOomAdjLocked(cpr.proc);
10756                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10757                // if the process has been successfully adjusted.  So to reduce races with
10758                // it, we will check whether the process still exists.  Note that this doesn't
10759                // completely get rid of races with LMK killing the process, but should make
10760                // them much smaller.
10761                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10762                    success = false;
10763                }
10764                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10765                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10766                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10767                // NOTE: there is still a race here where a signal could be
10768                // pending on the process even though we managed to update its
10769                // adj level.  Not sure what to do about this, but at least
10770                // the race is now smaller.
10771                if (!success) {
10772                    // Uh oh...  it looks like the provider's process
10773                    // has been killed on us.  We need to wait for a new
10774                    // process to be started, and make sure its death
10775                    // doesn't kill our process.
10776                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10777                            + " is crashing; detaching " + r);
10778                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10779                    checkTime(startTime, "getContentProviderImpl: before appDied");
10780                    appDiedLocked(cpr.proc);
10781                    checkTime(startTime, "getContentProviderImpl: after appDied");
10782                    if (!lastRef) {
10783                        // This wasn't the last ref our process had on
10784                        // the provider...  we have now been killed, bail.
10785                        return null;
10786                    }
10787                    providerRunning = false;
10788                    conn = null;
10789                } else {
10790                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10791                }
10792
10793                Binder.restoreCallingIdentity(origId);
10794            }
10795
10796            if (!providerRunning) {
10797                try {
10798                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10799                    cpi = AppGlobals.getPackageManager().
10800                        resolveContentProvider(name,
10801                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10802                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10803                } catch (RemoteException ex) {
10804                }
10805                if (cpi == null) {
10806                    return null;
10807                }
10808                // If the provider is a singleton AND
10809                // (it's a call within the same user || the provider is a
10810                // privileged app)
10811                // Then allow connecting to the singleton provider
10812                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10813                        cpi.name, cpi.flags)
10814                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10815                if (singleton) {
10816                    userId = UserHandle.USER_SYSTEM;
10817                }
10818                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10819                checkTime(startTime, "getContentProviderImpl: got app info for user");
10820
10821                String msg;
10822                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10823                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10824                        != null) {
10825                    throw new SecurityException(msg);
10826                }
10827                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10828
10829                if (!mProcessesReady
10830                        && !cpi.processName.equals("system")) {
10831                    // If this content provider does not run in the system
10832                    // process, and the system is not yet ready to run other
10833                    // processes, then fail fast instead of hanging.
10834                    throw new IllegalArgumentException(
10835                            "Attempt to launch content provider before system ready");
10836                }
10837
10838                // Make sure that the user who owns this provider is running.  If not,
10839                // we don't want to allow it to run.
10840                if (!mUserController.isUserRunningLocked(userId, 0)) {
10841                    Slog.w(TAG, "Unable to launch app "
10842                            + cpi.applicationInfo.packageName + "/"
10843                            + cpi.applicationInfo.uid + " for provider "
10844                            + name + ": user " + userId + " is stopped");
10845                    return null;
10846                }
10847
10848                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10849                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10850                cpr = mProviderMap.getProviderByClass(comp, userId);
10851                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10852                final boolean firstClass = cpr == null;
10853                if (firstClass) {
10854                    final long ident = Binder.clearCallingIdentity();
10855
10856                    // If permissions need a review before any of the app components can run,
10857                    // we return no provider and launch a review activity if the calling app
10858                    // is in the foreground.
10859                    if (mPermissionReviewRequired) {
10860                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10861                            return null;
10862                        }
10863                    }
10864
10865                    try {
10866                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10867                        ApplicationInfo ai =
10868                            AppGlobals.getPackageManager().
10869                                getApplicationInfo(
10870                                        cpi.applicationInfo.packageName,
10871                                        STOCK_PM_FLAGS, userId);
10872                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10873                        if (ai == null) {
10874                            Slog.w(TAG, "No package info for content provider "
10875                                    + cpi.name);
10876                            return null;
10877                        }
10878                        ai = getAppInfoForUser(ai, userId);
10879                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10880                    } catch (RemoteException ex) {
10881                        // pm is in same process, this will never happen.
10882                    } finally {
10883                        Binder.restoreCallingIdentity(ident);
10884                    }
10885                }
10886
10887                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10888
10889                if (r != null && cpr.canRunHere(r)) {
10890                    // If this is a multiprocess provider, then just return its
10891                    // info and allow the caller to instantiate it.  Only do
10892                    // this if the provider is the same user as the caller's
10893                    // process, or can run as root (so can be in any process).
10894                    return cpr.newHolder(null);
10895                }
10896
10897                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10898                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10899                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10900
10901                // This is single process, and our app is now connecting to it.
10902                // See if we are already in the process of launching this
10903                // provider.
10904                final int N = mLaunchingProviders.size();
10905                int i;
10906                for (i = 0; i < N; i++) {
10907                    if (mLaunchingProviders.get(i) == cpr) {
10908                        break;
10909                    }
10910                }
10911
10912                // If the provider is not already being launched, then get it
10913                // started.
10914                if (i >= N) {
10915                    final long origId = Binder.clearCallingIdentity();
10916
10917                    try {
10918                        // Content provider is now in use, its package can't be stopped.
10919                        try {
10920                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10921                            AppGlobals.getPackageManager().setPackageStoppedState(
10922                                    cpr.appInfo.packageName, false, userId);
10923                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10924                        } catch (RemoteException e) {
10925                        } catch (IllegalArgumentException e) {
10926                            Slog.w(TAG, "Failed trying to unstop package "
10927                                    + cpr.appInfo.packageName + ": " + e);
10928                        }
10929
10930                        // Use existing process if already started
10931                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10932                        ProcessRecord proc = getProcessRecordLocked(
10933                                cpi.processName, cpr.appInfo.uid, false);
10934                        if (proc != null && proc.thread != null && !proc.killed) {
10935                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10936                                    "Installing in existing process " + proc);
10937                            if (!proc.pubProviders.containsKey(cpi.name)) {
10938                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10939                                proc.pubProviders.put(cpi.name, cpr);
10940                                try {
10941                                    proc.thread.scheduleInstallProvider(cpi);
10942                                } catch (RemoteException e) {
10943                                }
10944                            }
10945                        } else {
10946                            checkTime(startTime, "getContentProviderImpl: before start process");
10947                            proc = startProcessLocked(cpi.processName,
10948                                    cpr.appInfo, false, 0, "content provider",
10949                                    new ComponentName(cpi.applicationInfo.packageName,
10950                                            cpi.name), false, false, false);
10951                            checkTime(startTime, "getContentProviderImpl: after start process");
10952                            if (proc == null) {
10953                                Slog.w(TAG, "Unable to launch app "
10954                                        + cpi.applicationInfo.packageName + "/"
10955                                        + cpi.applicationInfo.uid + " for provider "
10956                                        + name + ": process is bad");
10957                                return null;
10958                            }
10959                        }
10960                        cpr.launchingApp = proc;
10961                        mLaunchingProviders.add(cpr);
10962                    } finally {
10963                        Binder.restoreCallingIdentity(origId);
10964                    }
10965                }
10966
10967                checkTime(startTime, "getContentProviderImpl: updating data structures");
10968
10969                // Make sure the provider is published (the same provider class
10970                // may be published under multiple names).
10971                if (firstClass) {
10972                    mProviderMap.putProviderByClass(comp, cpr);
10973                }
10974
10975                mProviderMap.putProviderByName(name, cpr);
10976                conn = incProviderCountLocked(r, cpr, token, stable);
10977                if (conn != null) {
10978                    conn.waiting = true;
10979                }
10980            }
10981            checkTime(startTime, "getContentProviderImpl: done!");
10982        }
10983
10984        // Wait for the provider to be published...
10985        synchronized (cpr) {
10986            while (cpr.provider == null) {
10987                if (cpr.launchingApp == null) {
10988                    Slog.w(TAG, "Unable to launch app "
10989                            + cpi.applicationInfo.packageName + "/"
10990                            + cpi.applicationInfo.uid + " for provider "
10991                            + name + ": launching app became null");
10992                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10993                            UserHandle.getUserId(cpi.applicationInfo.uid),
10994                            cpi.applicationInfo.packageName,
10995                            cpi.applicationInfo.uid, name);
10996                    return null;
10997                }
10998                try {
10999                    if (DEBUG_MU) Slog.v(TAG_MU,
11000                            "Waiting to start provider " + cpr
11001                            + " launchingApp=" + cpr.launchingApp);
11002                    if (conn != null) {
11003                        conn.waiting = true;
11004                    }
11005                    cpr.wait();
11006                } catch (InterruptedException ex) {
11007                } finally {
11008                    if (conn != null) {
11009                        conn.waiting = false;
11010                    }
11011                }
11012            }
11013        }
11014        return cpr != null ? cpr.newHolder(conn) : null;
11015    }
11016
11017    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11018            ProcessRecord r, final int userId) {
11019        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11020                cpi.packageName, userId)) {
11021
11022            final boolean callerForeground = r == null || r.setSchedGroup
11023                    != ProcessList.SCHED_GROUP_BACKGROUND;
11024
11025            // Show a permission review UI only for starting from a foreground app
11026            if (!callerForeground) {
11027                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11028                        + cpi.packageName + " requires a permissions review");
11029                return false;
11030            }
11031
11032            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11033            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11034                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11035            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11036
11037            if (DEBUG_PERMISSIONS_REVIEW) {
11038                Slog.i(TAG, "u" + userId + " Launching permission review "
11039                        + "for package " + cpi.packageName);
11040            }
11041
11042            final UserHandle userHandle = new UserHandle(userId);
11043            mHandler.post(new Runnable() {
11044                @Override
11045                public void run() {
11046                    mContext.startActivityAsUser(intent, userHandle);
11047                }
11048            });
11049
11050            return false;
11051        }
11052
11053        return true;
11054    }
11055
11056    PackageManagerInternal getPackageManagerInternalLocked() {
11057        if (mPackageManagerInt == null) {
11058            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11059        }
11060        return mPackageManagerInt;
11061    }
11062
11063    @Override
11064    public final ContentProviderHolder getContentProvider(
11065            IApplicationThread caller, String name, int userId, boolean stable) {
11066        enforceNotIsolatedCaller("getContentProvider");
11067        if (caller == null) {
11068            String msg = "null IApplicationThread when getting content provider "
11069                    + name;
11070            Slog.w(TAG, msg);
11071            throw new SecurityException(msg);
11072        }
11073        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11074        // with cross-user grant.
11075        return getContentProviderImpl(caller, name, null, stable, userId);
11076    }
11077
11078    public ContentProviderHolder getContentProviderExternal(
11079            String name, int userId, IBinder token) {
11080        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11081            "Do not have permission in call getContentProviderExternal()");
11082        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11083                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11084        return getContentProviderExternalUnchecked(name, token, userId);
11085    }
11086
11087    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11088            IBinder token, int userId) {
11089        return getContentProviderImpl(null, name, token, true, userId);
11090    }
11091
11092    /**
11093     * Drop a content provider from a ProcessRecord's bookkeeping
11094     */
11095    public void removeContentProvider(IBinder connection, boolean stable) {
11096        enforceNotIsolatedCaller("removeContentProvider");
11097        long ident = Binder.clearCallingIdentity();
11098        try {
11099            synchronized (this) {
11100                ContentProviderConnection conn;
11101                try {
11102                    conn = (ContentProviderConnection)connection;
11103                } catch (ClassCastException e) {
11104                    String msg ="removeContentProvider: " + connection
11105                            + " not a ContentProviderConnection";
11106                    Slog.w(TAG, msg);
11107                    throw new IllegalArgumentException(msg);
11108                }
11109                if (conn == null) {
11110                    throw new NullPointerException("connection is null");
11111                }
11112                if (decProviderCountLocked(conn, null, null, stable)) {
11113                    updateOomAdjLocked();
11114                }
11115            }
11116        } finally {
11117            Binder.restoreCallingIdentity(ident);
11118        }
11119    }
11120
11121    public void removeContentProviderExternal(String name, IBinder token) {
11122        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11123            "Do not have permission in call removeContentProviderExternal()");
11124        int userId = UserHandle.getCallingUserId();
11125        long ident = Binder.clearCallingIdentity();
11126        try {
11127            removeContentProviderExternalUnchecked(name, token, userId);
11128        } finally {
11129            Binder.restoreCallingIdentity(ident);
11130        }
11131    }
11132
11133    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11134        synchronized (this) {
11135            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11136            if(cpr == null) {
11137                //remove from mProvidersByClass
11138                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11139                return;
11140            }
11141
11142            //update content provider record entry info
11143            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11144            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11145            if (localCpr.hasExternalProcessHandles()) {
11146                if (localCpr.removeExternalProcessHandleLocked(token)) {
11147                    updateOomAdjLocked();
11148                } else {
11149                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11150                            + " with no external reference for token: "
11151                            + token + ".");
11152                }
11153            } else {
11154                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11155                        + " with no external references.");
11156            }
11157        }
11158    }
11159
11160    public final void publishContentProviders(IApplicationThread caller,
11161            List<ContentProviderHolder> providers) {
11162        if (providers == null) {
11163            return;
11164        }
11165
11166        enforceNotIsolatedCaller("publishContentProviders");
11167        synchronized (this) {
11168            final ProcessRecord r = getRecordForAppLocked(caller);
11169            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11170            if (r == null) {
11171                throw new SecurityException(
11172                        "Unable to find app for caller " + caller
11173                      + " (pid=" + Binder.getCallingPid()
11174                      + ") when publishing content providers");
11175            }
11176
11177            final long origId = Binder.clearCallingIdentity();
11178
11179            final int N = providers.size();
11180            for (int i = 0; i < N; i++) {
11181                ContentProviderHolder src = providers.get(i);
11182                if (src == null || src.info == null || src.provider == null) {
11183                    continue;
11184                }
11185                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11186                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11187                if (dst != null) {
11188                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11189                    mProviderMap.putProviderByClass(comp, dst);
11190                    String names[] = dst.info.authority.split(";");
11191                    for (int j = 0; j < names.length; j++) {
11192                        mProviderMap.putProviderByName(names[j], dst);
11193                    }
11194
11195                    int launchingCount = mLaunchingProviders.size();
11196                    int j;
11197                    boolean wasInLaunchingProviders = false;
11198                    for (j = 0; j < launchingCount; j++) {
11199                        if (mLaunchingProviders.get(j) == dst) {
11200                            mLaunchingProviders.remove(j);
11201                            wasInLaunchingProviders = true;
11202                            j--;
11203                            launchingCount--;
11204                        }
11205                    }
11206                    if (wasInLaunchingProviders) {
11207                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11208                    }
11209                    synchronized (dst) {
11210                        dst.provider = src.provider;
11211                        dst.proc = r;
11212                        dst.notifyAll();
11213                    }
11214                    updateOomAdjLocked(r);
11215                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11216                            src.info.authority);
11217                }
11218            }
11219
11220            Binder.restoreCallingIdentity(origId);
11221        }
11222    }
11223
11224    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11225        ContentProviderConnection conn;
11226        try {
11227            conn = (ContentProviderConnection)connection;
11228        } catch (ClassCastException e) {
11229            String msg ="refContentProvider: " + connection
11230                    + " not a ContentProviderConnection";
11231            Slog.w(TAG, msg);
11232            throw new IllegalArgumentException(msg);
11233        }
11234        if (conn == null) {
11235            throw new NullPointerException("connection is null");
11236        }
11237
11238        synchronized (this) {
11239            if (stable > 0) {
11240                conn.numStableIncs += stable;
11241            }
11242            stable = conn.stableCount + stable;
11243            if (stable < 0) {
11244                throw new IllegalStateException("stableCount < 0: " + stable);
11245            }
11246
11247            if (unstable > 0) {
11248                conn.numUnstableIncs += unstable;
11249            }
11250            unstable = conn.unstableCount + unstable;
11251            if (unstable < 0) {
11252                throw new IllegalStateException("unstableCount < 0: " + unstable);
11253            }
11254
11255            if ((stable+unstable) <= 0) {
11256                throw new IllegalStateException("ref counts can't go to zero here: stable="
11257                        + stable + " unstable=" + unstable);
11258            }
11259            conn.stableCount = stable;
11260            conn.unstableCount = unstable;
11261            return !conn.dead;
11262        }
11263    }
11264
11265    public void unstableProviderDied(IBinder connection) {
11266        ContentProviderConnection conn;
11267        try {
11268            conn = (ContentProviderConnection)connection;
11269        } catch (ClassCastException e) {
11270            String msg ="refContentProvider: " + connection
11271                    + " not a ContentProviderConnection";
11272            Slog.w(TAG, msg);
11273            throw new IllegalArgumentException(msg);
11274        }
11275        if (conn == null) {
11276            throw new NullPointerException("connection is null");
11277        }
11278
11279        // Safely retrieve the content provider associated with the connection.
11280        IContentProvider provider;
11281        synchronized (this) {
11282            provider = conn.provider.provider;
11283        }
11284
11285        if (provider == null) {
11286            // Um, yeah, we're way ahead of you.
11287            return;
11288        }
11289
11290        // Make sure the caller is being honest with us.
11291        if (provider.asBinder().pingBinder()) {
11292            // Er, no, still looks good to us.
11293            synchronized (this) {
11294                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11295                        + " says " + conn + " died, but we don't agree");
11296                return;
11297            }
11298        }
11299
11300        // Well look at that!  It's dead!
11301        synchronized (this) {
11302            if (conn.provider.provider != provider) {
11303                // But something changed...  good enough.
11304                return;
11305            }
11306
11307            ProcessRecord proc = conn.provider.proc;
11308            if (proc == null || proc.thread == null) {
11309                // Seems like the process is already cleaned up.
11310                return;
11311            }
11312
11313            // As far as we're concerned, this is just like receiving a
11314            // death notification...  just a bit prematurely.
11315            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11316                    + ") early provider death");
11317            final long ident = Binder.clearCallingIdentity();
11318            try {
11319                appDiedLocked(proc);
11320            } finally {
11321                Binder.restoreCallingIdentity(ident);
11322            }
11323        }
11324    }
11325
11326    @Override
11327    public void appNotRespondingViaProvider(IBinder connection) {
11328        enforceCallingPermission(
11329                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11330
11331        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11332        if (conn == null) {
11333            Slog.w(TAG, "ContentProviderConnection is null");
11334            return;
11335        }
11336
11337        final ProcessRecord host = conn.provider.proc;
11338        if (host == null) {
11339            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11340            return;
11341        }
11342
11343        mHandler.post(new Runnable() {
11344            @Override
11345            public void run() {
11346                mAppErrors.appNotResponding(host, null, null, false,
11347                        "ContentProvider not responding");
11348            }
11349        });
11350    }
11351
11352    public final void installSystemProviders() {
11353        List<ProviderInfo> providers;
11354        synchronized (this) {
11355            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11356            providers = generateApplicationProvidersLocked(app);
11357            if (providers != null) {
11358                for (int i=providers.size()-1; i>=0; i--) {
11359                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11360                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11361                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11362                                + ": not system .apk");
11363                        providers.remove(i);
11364                    }
11365                }
11366            }
11367        }
11368        if (providers != null) {
11369            mSystemThread.installSystemProviders(providers);
11370        }
11371
11372        mCoreSettingsObserver = new CoreSettingsObserver(this);
11373        mFontScaleSettingObserver = new FontScaleSettingObserver();
11374
11375        //mUsageStatsService.monitorPackages();
11376    }
11377
11378    private void startPersistentApps(int matchFlags) {
11379        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11380
11381        synchronized (this) {
11382            try {
11383                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11384                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11385                for (ApplicationInfo app : apps) {
11386                    if (!"android".equals(app.packageName)) {
11387                        addAppLocked(app, false, null /* ABI override */);
11388                    }
11389                }
11390            } catch (RemoteException ex) {
11391            }
11392        }
11393    }
11394
11395    /**
11396     * When a user is unlocked, we need to install encryption-unaware providers
11397     * belonging to any running apps.
11398     */
11399    private void installEncryptionUnawareProviders(int userId) {
11400        // We're only interested in providers that are encryption unaware, and
11401        // we don't care about uninstalled apps, since there's no way they're
11402        // running at this point.
11403        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11404
11405        synchronized (this) {
11406            final int NP = mProcessNames.getMap().size();
11407            for (int ip = 0; ip < NP; ip++) {
11408                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11409                final int NA = apps.size();
11410                for (int ia = 0; ia < NA; ia++) {
11411                    final ProcessRecord app = apps.valueAt(ia);
11412                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11413
11414                    final int NG = app.pkgList.size();
11415                    for (int ig = 0; ig < NG; ig++) {
11416                        try {
11417                            final String pkgName = app.pkgList.keyAt(ig);
11418                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11419                                    .getPackageInfo(pkgName, matchFlags, userId);
11420                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11421                                for (ProviderInfo pi : pkgInfo.providers) {
11422                                    // TODO: keep in sync with generateApplicationProvidersLocked
11423                                    final boolean processMatch = Objects.equals(pi.processName,
11424                                            app.processName) || pi.multiprocess;
11425                                    final boolean userMatch = isSingleton(pi.processName,
11426                                            pi.applicationInfo, pi.name, pi.flags)
11427                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11428                                    if (processMatch && userMatch) {
11429                                        Log.v(TAG, "Installing " + pi);
11430                                        app.thread.scheduleInstallProvider(pi);
11431                                    } else {
11432                                        Log.v(TAG, "Skipping " + pi);
11433                                    }
11434                                }
11435                            }
11436                        } catch (RemoteException ignored) {
11437                        }
11438                    }
11439                }
11440            }
11441        }
11442    }
11443
11444    /**
11445     * Allows apps to retrieve the MIME type of a URI.
11446     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11447     * users, then it does not need permission to access the ContentProvider.
11448     * Either, it needs cross-user uri grants.
11449     *
11450     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11451     *
11452     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11453     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11454     */
11455    public String getProviderMimeType(Uri uri, int userId) {
11456        enforceNotIsolatedCaller("getProviderMimeType");
11457        final String name = uri.getAuthority();
11458        int callingUid = Binder.getCallingUid();
11459        int callingPid = Binder.getCallingPid();
11460        long ident = 0;
11461        boolean clearedIdentity = false;
11462        synchronized (this) {
11463            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11464        }
11465        if (canClearIdentity(callingPid, callingUid, userId)) {
11466            clearedIdentity = true;
11467            ident = Binder.clearCallingIdentity();
11468        }
11469        ContentProviderHolder holder = null;
11470        try {
11471            holder = getContentProviderExternalUnchecked(name, null, userId);
11472            if (holder != null) {
11473                return holder.provider.getType(uri);
11474            }
11475        } catch (RemoteException e) {
11476            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11477            return null;
11478        } catch (Exception e) {
11479            Log.w(TAG, "Exception while determining type of " + uri, e);
11480            return null;
11481        } finally {
11482            // We need to clear the identity to call removeContentProviderExternalUnchecked
11483            if (!clearedIdentity) {
11484                ident = Binder.clearCallingIdentity();
11485            }
11486            try {
11487                if (holder != null) {
11488                    removeContentProviderExternalUnchecked(name, null, userId);
11489                }
11490            } finally {
11491                Binder.restoreCallingIdentity(ident);
11492            }
11493        }
11494
11495        return null;
11496    }
11497
11498    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11499        if (UserHandle.getUserId(callingUid) == userId) {
11500            return true;
11501        }
11502        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11503                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11504                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11505                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11506                return true;
11507        }
11508        return false;
11509    }
11510
11511    // =========================================================
11512    // GLOBAL MANAGEMENT
11513    // =========================================================
11514
11515    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11516            boolean isolated, int isolatedUid) {
11517        String proc = customProcess != null ? customProcess : info.processName;
11518        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11519        final int userId = UserHandle.getUserId(info.uid);
11520        int uid = info.uid;
11521        if (isolated) {
11522            if (isolatedUid == 0) {
11523                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11524                while (true) {
11525                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11526                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11527                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11528                    }
11529                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11530                    mNextIsolatedProcessUid++;
11531                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11532                        // No process for this uid, use it.
11533                        break;
11534                    }
11535                    stepsLeft--;
11536                    if (stepsLeft <= 0) {
11537                        return null;
11538                    }
11539                }
11540            } else {
11541                // Special case for startIsolatedProcess (internal only), where
11542                // the uid of the isolated process is specified by the caller.
11543                uid = isolatedUid;
11544            }
11545
11546            // Register the isolated UID with this application so BatteryStats knows to
11547            // attribute resource usage to the application.
11548            //
11549            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11550            // about the process state of the isolated UID *before* it is registered with the
11551            // owning application.
11552            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11553        }
11554        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11555        if (!mBooted && !mBooting
11556                && userId == UserHandle.USER_SYSTEM
11557                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11558            r.persistent = true;
11559            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11560        }
11561        addProcessNameLocked(r);
11562        return r;
11563    }
11564
11565    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11566            String abiOverride) {
11567        ProcessRecord app;
11568        if (!isolated) {
11569            app = getProcessRecordLocked(info.processName, info.uid, true);
11570        } else {
11571            app = null;
11572        }
11573
11574        if (app == null) {
11575            app = newProcessRecordLocked(info, null, isolated, 0);
11576            updateLruProcessLocked(app, false, null);
11577            updateOomAdjLocked();
11578        }
11579
11580        // This package really, really can not be stopped.
11581        try {
11582            AppGlobals.getPackageManager().setPackageStoppedState(
11583                    info.packageName, false, UserHandle.getUserId(app.uid));
11584        } catch (RemoteException e) {
11585        } catch (IllegalArgumentException e) {
11586            Slog.w(TAG, "Failed trying to unstop package "
11587                    + info.packageName + ": " + e);
11588        }
11589
11590        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11591            app.persistent = true;
11592            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11593        }
11594        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11595            mPersistentStartingProcesses.add(app);
11596            startProcessLocked(app, "added application", app.processName, abiOverride,
11597                    null /* entryPoint */, null /* entryPointArgs */);
11598        }
11599
11600        return app;
11601    }
11602
11603    public void unhandledBack() {
11604        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11605                "unhandledBack()");
11606
11607        synchronized(this) {
11608            final long origId = Binder.clearCallingIdentity();
11609            try {
11610                getFocusedStack().unhandledBackLocked();
11611            } finally {
11612                Binder.restoreCallingIdentity(origId);
11613            }
11614        }
11615    }
11616
11617    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11618        enforceNotIsolatedCaller("openContentUri");
11619        final int userId = UserHandle.getCallingUserId();
11620        final Uri uri = Uri.parse(uriString);
11621        String name = uri.getAuthority();
11622        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11623        ParcelFileDescriptor pfd = null;
11624        if (cph != null) {
11625            // We record the binder invoker's uid in thread-local storage before
11626            // going to the content provider to open the file.  Later, in the code
11627            // that handles all permissions checks, we look for this uid and use
11628            // that rather than the Activity Manager's own uid.  The effect is that
11629            // we do the check against the caller's permissions even though it looks
11630            // to the content provider like the Activity Manager itself is making
11631            // the request.
11632            Binder token = new Binder();
11633            sCallerIdentity.set(new Identity(
11634                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11635            try {
11636                pfd = cph.provider.openFile(null, uri, "r", null, token);
11637            } catch (FileNotFoundException e) {
11638                // do nothing; pfd will be returned null
11639            } finally {
11640                // Ensure that whatever happens, we clean up the identity state
11641                sCallerIdentity.remove();
11642                // Ensure we're done with the provider.
11643                removeContentProviderExternalUnchecked(name, null, userId);
11644            }
11645        } else {
11646            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11647        }
11648        return pfd;
11649    }
11650
11651    // Actually is sleeping or shutting down or whatever else in the future
11652    // is an inactive state.
11653    boolean isSleepingOrShuttingDownLocked() {
11654        return isSleepingLocked() || mShuttingDown;
11655    }
11656
11657    boolean isShuttingDownLocked() {
11658        return mShuttingDown;
11659    }
11660
11661    boolean isSleepingLocked() {
11662        return mSleeping;
11663    }
11664
11665    void onWakefulnessChanged(int wakefulness) {
11666        synchronized(this) {
11667            mWakefulness = wakefulness;
11668            updateSleepIfNeededLocked();
11669        }
11670    }
11671
11672    void finishRunningVoiceLocked() {
11673        if (mRunningVoice != null) {
11674            mRunningVoice = null;
11675            mVoiceWakeLock.release();
11676            updateSleepIfNeededLocked();
11677        }
11678    }
11679
11680    void startTimeTrackingFocusedActivityLocked() {
11681        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11682        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11683            mCurAppTimeTracker.start(resumedActivity.packageName);
11684        }
11685    }
11686
11687    void updateSleepIfNeededLocked() {
11688        if (mSleeping && !shouldSleepLocked()) {
11689            mSleeping = false;
11690            startTimeTrackingFocusedActivityLocked();
11691            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11692            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11693            sendNotifyVrManagerOfSleepState(false);
11694            updateOomAdjLocked();
11695        } else if (!mSleeping && shouldSleepLocked()) {
11696            mSleeping = true;
11697            if (mCurAppTimeTracker != null) {
11698                mCurAppTimeTracker.stop();
11699            }
11700            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11701            mStackSupervisor.goingToSleepLocked();
11702            sendNotifyVrManagerOfSleepState(true);
11703            updateOomAdjLocked();
11704
11705            // Initialize the wake times of all processes.
11706            checkExcessivePowerUsageLocked(false);
11707            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11708            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11709            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11710        }
11711    }
11712
11713    private boolean shouldSleepLocked() {
11714        // Resume applications while running a voice interactor.
11715        if (mRunningVoice != null) {
11716            return false;
11717        }
11718
11719        // TODO: Transform the lock screen state into a sleep token instead.
11720        switch (mWakefulness) {
11721            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11722            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11723            case PowerManagerInternal.WAKEFULNESS_DOZING:
11724                // Pause applications whenever the lock screen is shown or any sleep
11725                // tokens have been acquired.
11726                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
11727            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11728            default:
11729                // If we're asleep then pause applications unconditionally.
11730                return true;
11731        }
11732    }
11733
11734    /** Pokes the task persister. */
11735    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11736        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11737    }
11738
11739    /** Notifies all listeners when the pinned stack animation ends. */
11740    @Override
11741    public void notifyPinnedStackAnimationEnded() {
11742        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11743    }
11744
11745    @Override
11746    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11747        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11748    }
11749
11750    @Override
11751    public boolean shutdown(int timeout) {
11752        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11753                != PackageManager.PERMISSION_GRANTED) {
11754            throw new SecurityException("Requires permission "
11755                    + android.Manifest.permission.SHUTDOWN);
11756        }
11757
11758        boolean timedout = false;
11759
11760        synchronized(this) {
11761            mShuttingDown = true;
11762            updateEventDispatchingLocked();
11763            timedout = mStackSupervisor.shutdownLocked(timeout);
11764        }
11765
11766        mAppOpsService.shutdown();
11767        if (mUsageStatsService != null) {
11768            mUsageStatsService.prepareShutdown();
11769        }
11770        mBatteryStatsService.shutdown();
11771        synchronized (this) {
11772            mProcessStats.shutdownLocked();
11773            notifyTaskPersisterLocked(null, true);
11774        }
11775
11776        return timedout;
11777    }
11778
11779    public final void activitySlept(IBinder token) {
11780        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11781
11782        final long origId = Binder.clearCallingIdentity();
11783
11784        synchronized (this) {
11785            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11786            if (r != null) {
11787                mStackSupervisor.activitySleptLocked(r);
11788            }
11789        }
11790
11791        Binder.restoreCallingIdentity(origId);
11792    }
11793
11794    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11795        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11796        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11797        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11798            boolean wasRunningVoice = mRunningVoice != null;
11799            mRunningVoice = session;
11800            if (!wasRunningVoice) {
11801                mVoiceWakeLock.acquire();
11802                updateSleepIfNeededLocked();
11803            }
11804        }
11805    }
11806
11807    private void updateEventDispatchingLocked() {
11808        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11809    }
11810
11811    @Override
11812    public void setLockScreenShown(boolean showing) {
11813        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11814                != PackageManager.PERMISSION_GRANTED) {
11815            throw new SecurityException("Requires permission "
11816                    + android.Manifest.permission.DEVICE_POWER);
11817        }
11818
11819        synchronized(this) {
11820            long ident = Binder.clearCallingIdentity();
11821            try {
11822                mKeyguardController.setKeyguardShown(showing);
11823            } finally {
11824                Binder.restoreCallingIdentity(ident);
11825            }
11826        }
11827    }
11828
11829    @Override
11830    public void notifyLockedProfile(@UserIdInt int userId) {
11831        try {
11832            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11833                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11834            }
11835        } catch (RemoteException ex) {
11836            throw new SecurityException("Fail to check is caller a privileged app", ex);
11837        }
11838
11839        synchronized (this) {
11840            if (mStackSupervisor.isUserLockedProfile(userId)) {
11841                final long ident = Binder.clearCallingIdentity();
11842                try {
11843                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11844                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11845                        // If there is no device lock, we will show the profile's credential page.
11846                        mActivityStarter.showConfirmDeviceCredential(userId);
11847                    } else {
11848                        // Showing launcher to avoid user entering credential twice.
11849                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11850                    }
11851                } finally {
11852                    Binder.restoreCallingIdentity(ident);
11853                }
11854            }
11855        }
11856    }
11857
11858    @Override
11859    public void startConfirmDeviceCredentialIntent(Intent intent) {
11860        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11861        synchronized (this) {
11862            final long ident = Binder.clearCallingIdentity();
11863            try {
11864                mActivityStarter.startConfirmCredentialIntent(intent);
11865            } finally {
11866                Binder.restoreCallingIdentity(ident);
11867            }
11868        }
11869    }
11870
11871    @Override
11872    public void stopAppSwitches() {
11873        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11874                != PackageManager.PERMISSION_GRANTED) {
11875            throw new SecurityException("viewquires permission "
11876                    + android.Manifest.permission.STOP_APP_SWITCHES);
11877        }
11878
11879        synchronized(this) {
11880            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11881                    + APP_SWITCH_DELAY_TIME;
11882            mDidAppSwitch = false;
11883            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11884            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11885            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11886        }
11887    }
11888
11889    public void resumeAppSwitches() {
11890        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11891                != PackageManager.PERMISSION_GRANTED) {
11892            throw new SecurityException("Requires permission "
11893                    + android.Manifest.permission.STOP_APP_SWITCHES);
11894        }
11895
11896        synchronized(this) {
11897            // Note that we don't execute any pending app switches... we will
11898            // let those wait until either the timeout, or the next start
11899            // activity request.
11900            mAppSwitchesAllowedTime = 0;
11901        }
11902    }
11903
11904    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11905            int callingPid, int callingUid, String name) {
11906        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11907            return true;
11908        }
11909
11910        int perm = checkComponentPermission(
11911                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11912                sourceUid, -1, true);
11913        if (perm == PackageManager.PERMISSION_GRANTED) {
11914            return true;
11915        }
11916
11917        // If the actual IPC caller is different from the logical source, then
11918        // also see if they are allowed to control app switches.
11919        if (callingUid != -1 && callingUid != sourceUid) {
11920            perm = checkComponentPermission(
11921                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11922                    callingUid, -1, true);
11923            if (perm == PackageManager.PERMISSION_GRANTED) {
11924                return true;
11925            }
11926        }
11927
11928        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11929        return false;
11930    }
11931
11932    public void setDebugApp(String packageName, boolean waitForDebugger,
11933            boolean persistent) {
11934        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11935                "setDebugApp()");
11936
11937        long ident = Binder.clearCallingIdentity();
11938        try {
11939            // Note that this is not really thread safe if there are multiple
11940            // callers into it at the same time, but that's not a situation we
11941            // care about.
11942            if (persistent) {
11943                final ContentResolver resolver = mContext.getContentResolver();
11944                Settings.Global.putString(
11945                    resolver, Settings.Global.DEBUG_APP,
11946                    packageName);
11947                Settings.Global.putInt(
11948                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11949                    waitForDebugger ? 1 : 0);
11950            }
11951
11952            synchronized (this) {
11953                if (!persistent) {
11954                    mOrigDebugApp = mDebugApp;
11955                    mOrigWaitForDebugger = mWaitForDebugger;
11956                }
11957                mDebugApp = packageName;
11958                mWaitForDebugger = waitForDebugger;
11959                mDebugTransient = !persistent;
11960                if (packageName != null) {
11961                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11962                            false, UserHandle.USER_ALL, "set debug app");
11963                }
11964            }
11965        } finally {
11966            Binder.restoreCallingIdentity(ident);
11967        }
11968    }
11969
11970    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11971        synchronized (this) {
11972            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11973            if (!isDebuggable) {
11974                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11975                    throw new SecurityException("Process not debuggable: " + app.packageName);
11976                }
11977            }
11978
11979            mTrackAllocationApp = processName;
11980        }
11981    }
11982
11983    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11984        synchronized (this) {
11985            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11986            if (!isDebuggable) {
11987                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11988                    throw new SecurityException("Process not debuggable: " + app.packageName);
11989                }
11990            }
11991            mProfileApp = processName;
11992            mProfileFile = profilerInfo.profileFile;
11993            if (mProfileFd != null) {
11994                try {
11995                    mProfileFd.close();
11996                } catch (IOException e) {
11997                }
11998                mProfileFd = null;
11999            }
12000            mProfileFd = profilerInfo.profileFd;
12001            mSamplingInterval = profilerInfo.samplingInterval;
12002            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12003            mProfileType = 0;
12004        }
12005    }
12006
12007    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12008        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12009        if (!isDebuggable) {
12010            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12011                throw new SecurityException("Process not debuggable: " + app.packageName);
12012            }
12013        }
12014        mNativeDebuggingApp = processName;
12015    }
12016
12017    @Override
12018    public void setAlwaysFinish(boolean enabled) {
12019        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12020                "setAlwaysFinish()");
12021
12022        long ident = Binder.clearCallingIdentity();
12023        try {
12024            Settings.Global.putInt(
12025                    mContext.getContentResolver(),
12026                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12027
12028            synchronized (this) {
12029                mAlwaysFinishActivities = enabled;
12030            }
12031        } finally {
12032            Binder.restoreCallingIdentity(ident);
12033        }
12034    }
12035
12036    @Override
12037    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12038        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12039                "setActivityController()");
12040        synchronized (this) {
12041            mController = controller;
12042            mControllerIsAMonkey = imAMonkey;
12043            Watchdog.getInstance().setActivityController(controller);
12044        }
12045    }
12046
12047    @Override
12048    public void setUserIsMonkey(boolean userIsMonkey) {
12049        synchronized (this) {
12050            synchronized (mPidsSelfLocked) {
12051                final int callingPid = Binder.getCallingPid();
12052                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12053                if (precessRecord == null) {
12054                    throw new SecurityException("Unknown process: " + callingPid);
12055                }
12056                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12057                    throw new SecurityException("Only an instrumentation process "
12058                            + "with a UiAutomation can call setUserIsMonkey");
12059                }
12060            }
12061            mUserIsMonkey = userIsMonkey;
12062        }
12063    }
12064
12065    @Override
12066    public boolean isUserAMonkey() {
12067        synchronized (this) {
12068            // If there is a controller also implies the user is a monkey.
12069            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12070        }
12071    }
12072
12073    /**
12074     * @deprecated This method is only used by a few internal components and it will soon be
12075     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12076     * No new code should be calling it.
12077     */
12078    @Deprecated
12079    public void requestBugReport(int bugreportType) {
12080        String extraOptions = null;
12081        switch (bugreportType) {
12082            case ActivityManager.BUGREPORT_OPTION_FULL:
12083                // Default options.
12084                break;
12085            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12086                extraOptions = "bugreportplus";
12087                break;
12088            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12089                extraOptions = "bugreportremote";
12090                break;
12091            case ActivityManager.BUGREPORT_OPTION_WEAR:
12092                extraOptions = "bugreportwear";
12093                break;
12094            default:
12095                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12096                        + bugreportType);
12097        }
12098        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12099        if (extraOptions != null) {
12100            SystemProperties.set("dumpstate.options", extraOptions);
12101        }
12102        SystemProperties.set("ctl.start", "bugreport");
12103    }
12104
12105    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12106        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12107    }
12108
12109    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12110        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12111            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12112        }
12113        return KEY_DISPATCHING_TIMEOUT;
12114    }
12115
12116    @Override
12117    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12118        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12119                != PackageManager.PERMISSION_GRANTED) {
12120            throw new SecurityException("Requires permission "
12121                    + android.Manifest.permission.FILTER_EVENTS);
12122        }
12123        ProcessRecord proc;
12124        long timeout;
12125        synchronized (this) {
12126            synchronized (mPidsSelfLocked) {
12127                proc = mPidsSelfLocked.get(pid);
12128            }
12129            timeout = getInputDispatchingTimeoutLocked(proc);
12130        }
12131
12132        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12133            return -1;
12134        }
12135
12136        return timeout;
12137    }
12138
12139    /**
12140     * Handle input dispatching timeouts.
12141     * Returns whether input dispatching should be aborted or not.
12142     */
12143    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12144            final ActivityRecord activity, final ActivityRecord parent,
12145            final boolean aboveSystem, String reason) {
12146        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12147                != PackageManager.PERMISSION_GRANTED) {
12148            throw new SecurityException("Requires permission "
12149                    + android.Manifest.permission.FILTER_EVENTS);
12150        }
12151
12152        final String annotation;
12153        if (reason == null) {
12154            annotation = "Input dispatching timed out";
12155        } else {
12156            annotation = "Input dispatching timed out (" + reason + ")";
12157        }
12158
12159        if (proc != null) {
12160            synchronized (this) {
12161                if (proc.debugging) {
12162                    return false;
12163                }
12164
12165                if (mDidDexOpt) {
12166                    // Give more time since we were dexopting.
12167                    mDidDexOpt = false;
12168                    return false;
12169                }
12170
12171                if (proc.instrumentationClass != null) {
12172                    Bundle info = new Bundle();
12173                    info.putString("shortMsg", "keyDispatchingTimedOut");
12174                    info.putString("longMsg", annotation);
12175                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12176                    return true;
12177                }
12178            }
12179            mHandler.post(new Runnable() {
12180                @Override
12181                public void run() {
12182                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12183                }
12184            });
12185        }
12186
12187        return true;
12188    }
12189
12190    @Override
12191    public Bundle getAssistContextExtras(int requestType) {
12192        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12193                null, null, true /* focused */, true /* newSessionId */,
12194                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12195        if (pae == null) {
12196            return null;
12197        }
12198        synchronized (pae) {
12199            while (!pae.haveResult) {
12200                try {
12201                    pae.wait();
12202                } catch (InterruptedException e) {
12203                }
12204            }
12205        }
12206        synchronized (this) {
12207            buildAssistBundleLocked(pae, pae.result);
12208            mPendingAssistExtras.remove(pae);
12209            mUiHandler.removeCallbacks(pae);
12210        }
12211        return pae.extras;
12212    }
12213
12214    @Override
12215    public boolean isAssistDataAllowedOnCurrentActivity() {
12216        int userId;
12217        synchronized (this) {
12218            userId = mUserController.getCurrentUserIdLocked();
12219            ActivityRecord activity = getFocusedStack().topActivity();
12220            if (activity == null) {
12221                return false;
12222            }
12223            userId = activity.userId;
12224        }
12225        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12226                Context.DEVICE_POLICY_SERVICE);
12227        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12228    }
12229
12230    @Override
12231    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12232        long ident = Binder.clearCallingIdentity();
12233        try {
12234            synchronized (this) {
12235                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12236                ActivityRecord top = getFocusedStack().topActivity();
12237                if (top != caller) {
12238                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12239                            + " is not current top " + top);
12240                    return false;
12241                }
12242                if (!top.nowVisible) {
12243                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12244                            + " is not visible");
12245                    return false;
12246                }
12247            }
12248            AssistUtils utils = new AssistUtils(mContext);
12249            return utils.showSessionForActiveService(args,
12250                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12251        } finally {
12252            Binder.restoreCallingIdentity(ident);
12253        }
12254    }
12255
12256    @Override
12257    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12258            Bundle receiverExtras,
12259            IBinder activityToken, boolean focused, boolean newSessionId) {
12260        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12261                activityToken, focused, newSessionId,
12262                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0)
12263                != null;
12264    }
12265
12266    @Override
12267    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
12268            IBinder activityToken, int flags) {
12269        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_FULL, null, null, receiver,
12270                receiverExtras, activityToken, true, true,
12271                UserHandle.getCallingUserId(), null, PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT,
12272                flags) != null;
12273    }
12274
12275    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12276            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12277            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
12278            int flags) {
12279        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12280                "enqueueAssistContext()");
12281        synchronized (this) {
12282            ActivityRecord activity = getFocusedStack().topActivity();
12283            if (activity == null) {
12284                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12285                return null;
12286            }
12287            if (activity.app == null || activity.app.thread == null) {
12288                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12289                return null;
12290            }
12291            if (focused) {
12292                if (activityToken != null) {
12293                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12294                    if (activity != caller) {
12295                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12296                                + " is not current top " + activity);
12297                        return null;
12298                    }
12299                }
12300            } else {
12301                activity = ActivityRecord.forTokenLocked(activityToken);
12302                if (activity == null) {
12303                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12304                            + " couldn't be found");
12305                    return null;
12306                }
12307            }
12308
12309            PendingAssistExtras pae;
12310            Bundle extras = new Bundle();
12311            if (args != null) {
12312                extras.putAll(args);
12313            }
12314            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12315            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12316            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12317                    flags, userHandle);
12318            // Increment the sessionId if necessary
12319            if (newSessionId) {
12320                mViSessionId++;
12321            }
12322            try {
12323                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12324                        requestType, mViSessionId, flags);
12325                mPendingAssistExtras.add(pae);
12326                mUiHandler.postDelayed(pae, timeout);
12327            } catch (RemoteException e) {
12328                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12329                return null;
12330            }
12331            return pae;
12332        }
12333    }
12334
12335    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12336        IResultReceiver receiver;
12337        synchronized (this) {
12338            mPendingAssistExtras.remove(pae);
12339            receiver = pae.receiver;
12340        }
12341        if (receiver != null) {
12342            // Caller wants result sent back to them.
12343            Bundle sendBundle = new Bundle();
12344            // At least return the receiver extras
12345            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12346                    pae.receiverExtras);
12347            try {
12348                pae.receiver.send(0, sendBundle);
12349            } catch (RemoteException e) {
12350            }
12351        }
12352    }
12353
12354    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12355        if (result != null) {
12356            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12357        }
12358        if (pae.hint != null) {
12359            pae.extras.putBoolean(pae.hint, true);
12360        }
12361    }
12362
12363    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12364            AssistContent content, Uri referrer) {
12365        PendingAssistExtras pae = (PendingAssistExtras)token;
12366        synchronized (pae) {
12367            pae.result = extras;
12368            pae.structure = structure;
12369            pae.content = content;
12370            if (referrer != null) {
12371                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12372            }
12373            pae.haveResult = true;
12374            pae.notifyAll();
12375            if (pae.intent == null && pae.receiver == null) {
12376                // Caller is just waiting for the result.
12377                return;
12378            }
12379        }
12380
12381        // We are now ready to launch the assist activity.
12382        IResultReceiver sendReceiver = null;
12383        Bundle sendBundle = null;
12384        synchronized (this) {
12385            buildAssistBundleLocked(pae, extras);
12386            boolean exists = mPendingAssistExtras.remove(pae);
12387            mUiHandler.removeCallbacks(pae);
12388            if (!exists) {
12389                // Timed out.
12390                return;
12391            }
12392            if ((sendReceiver=pae.receiver) != null) {
12393                // Caller wants result sent back to them.
12394                sendBundle = new Bundle();
12395                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12396                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12397                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12398                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12399                        pae.receiverExtras);
12400                if (pae.flags > 0) {
12401                    sendBundle.putInt(VoiceInteractionSession.KEY_FLAGS, pae.flags);
12402                }
12403                IBinder autoFillCallback =
12404                        extras.getBinder(AutoFillService.KEY_CALLBACK);
12405                if (autoFillCallback != null) {
12406                    sendBundle.putBinder(AutoFillService.KEY_CALLBACK,
12407                            autoFillCallback);
12408                }
12409            }
12410        }
12411        if (sendReceiver != null) {
12412            try {
12413                sendReceiver.send(0, sendBundle);
12414            } catch (RemoteException e) {
12415            }
12416            return;
12417        }
12418
12419        long ident = Binder.clearCallingIdentity();
12420        try {
12421            pae.intent.replaceExtras(pae.extras);
12422            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12423                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12424                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12425            closeSystemDialogs("assist");
12426            try {
12427                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12428            } catch (ActivityNotFoundException e) {
12429                Slog.w(TAG, "No activity to handle assist action.", e);
12430            }
12431        } finally {
12432            Binder.restoreCallingIdentity(ident);
12433        }
12434    }
12435
12436    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12437            Bundle args) {
12438        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12439                true /* focused */, true /* newSessionId */,
12440                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
12441    }
12442
12443    public void registerProcessObserver(IProcessObserver observer) {
12444        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12445                "registerProcessObserver()");
12446        synchronized (this) {
12447            mProcessObservers.register(observer);
12448        }
12449    }
12450
12451    @Override
12452    public void unregisterProcessObserver(IProcessObserver observer) {
12453        synchronized (this) {
12454            mProcessObservers.unregister(observer);
12455        }
12456    }
12457
12458    @Override
12459    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12460            String callingPackage) {
12461        if (!hasUsageStatsPermission(callingPackage)) {
12462            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12463                    "registerUidObserver");
12464        }
12465        synchronized (this) {
12466            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12467                    callingPackage, which, cutpoint));
12468        }
12469    }
12470
12471    @Override
12472    public void unregisterUidObserver(IUidObserver observer) {
12473        synchronized (this) {
12474            mUidObservers.unregister(observer);
12475        }
12476    }
12477
12478    @Override
12479    public boolean convertFromTranslucent(IBinder token) {
12480        final long origId = Binder.clearCallingIdentity();
12481        try {
12482            synchronized (this) {
12483                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12484                if (r == null) {
12485                    return false;
12486                }
12487                final boolean translucentChanged = r.changeWindowTranslucency(true);
12488                if (translucentChanged) {
12489                    r.getStack().releaseBackgroundResources(r);
12490                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12491                }
12492                mWindowManager.setAppFullscreen(token, true);
12493                return translucentChanged;
12494            }
12495        } finally {
12496            Binder.restoreCallingIdentity(origId);
12497        }
12498    }
12499
12500    @Override
12501    public boolean convertToTranslucent(IBinder token, Bundle options) {
12502        final long origId = Binder.clearCallingIdentity();
12503        try {
12504            synchronized (this) {
12505                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12506                if (r == null) {
12507                    return false;
12508                }
12509                int index = r.task.mActivities.lastIndexOf(r);
12510                if (index > 0) {
12511                    ActivityRecord under = r.task.mActivities.get(index - 1);
12512                    under.returningOptions = ActivityOptions.fromBundle(options);
12513                }
12514                final boolean translucentChanged = r.changeWindowTranslucency(false);
12515                if (translucentChanged) {
12516                    r.getStack().convertActivityToTranslucent(r);
12517                }
12518                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12519                mWindowManager.setAppFullscreen(token, false);
12520                return translucentChanged;
12521            }
12522        } finally {
12523            Binder.restoreCallingIdentity(origId);
12524        }
12525    }
12526
12527    @Override
12528    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12529        final long origId = Binder.clearCallingIdentity();
12530        try {
12531            synchronized (this) {
12532                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12533                if (r != null) {
12534                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12535                }
12536            }
12537            return false;
12538        } finally {
12539            Binder.restoreCallingIdentity(origId);
12540        }
12541    }
12542
12543    @Override
12544    public boolean isBackgroundVisibleBehind(IBinder token) {
12545        final long origId = Binder.clearCallingIdentity();
12546        try {
12547            synchronized (this) {
12548                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12549                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12550                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12551                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12552                return visible;
12553            }
12554        } finally {
12555            Binder.restoreCallingIdentity(origId);
12556        }
12557    }
12558
12559    @Override
12560    public Bundle getActivityOptions(IBinder token) {
12561        final long origId = Binder.clearCallingIdentity();
12562        try {
12563            synchronized (this) {
12564                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12565                if (r != null) {
12566                    final ActivityOptions activityOptions = r.pendingOptions;
12567                    r.pendingOptions = null;
12568                    return activityOptions == null ? null : activityOptions.toBundle();
12569                }
12570                return null;
12571            }
12572        } finally {
12573            Binder.restoreCallingIdentity(origId);
12574        }
12575    }
12576
12577    @Override
12578    public void setImmersive(IBinder token, boolean immersive) {
12579        synchronized(this) {
12580            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12581            if (r == null) {
12582                throw new IllegalArgumentException();
12583            }
12584            r.immersive = immersive;
12585
12586            // update associated state if we're frontmost
12587            if (r == mStackSupervisor.getResumedActivityLocked()) {
12588                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12589                applyUpdateLockStateLocked(r);
12590            }
12591        }
12592    }
12593
12594    @Override
12595    public boolean isImmersive(IBinder token) {
12596        synchronized (this) {
12597            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12598            if (r == null) {
12599                throw new IllegalArgumentException();
12600            }
12601            return r.immersive;
12602        }
12603    }
12604
12605    public void setVrThread(int tid) {
12606        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12607            throw new UnsupportedOperationException("VR mode not supported on this device!");
12608        }
12609
12610        synchronized (this) {
12611            ProcessRecord proc;
12612            synchronized (mPidsSelfLocked) {
12613                final int pid = Binder.getCallingPid();
12614                proc = mPidsSelfLocked.get(pid);
12615
12616                if (proc != null && mInVrMode && tid >= 0) {
12617                    // ensure the tid belongs to the process
12618                    if (!Process.isThreadInProcess(pid, tid)) {
12619                        throw new IllegalArgumentException("VR thread does not belong to process");
12620                    }
12621
12622                    // reset existing VR thread to CFS if this thread still exists and belongs to
12623                    // the calling process
12624                    if (proc.vrThreadTid != 0
12625                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12626                        try {
12627                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12628                        } catch (IllegalArgumentException e) {
12629                            // Ignore this.  Only occurs in race condition where previous VR thread
12630                            // was destroyed during this method call.
12631                        }
12632                    }
12633
12634                    proc.vrThreadTid = tid;
12635
12636                    // promote to FIFO now if the tid is non-zero
12637                    try {
12638                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12639                            proc.vrThreadTid > 0) {
12640                            Process.setThreadScheduler(proc.vrThreadTid,
12641                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12642                        }
12643                    } catch (IllegalArgumentException e) {
12644                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12645                               + " not exist:\n" + e);
12646                    }
12647                }
12648            }
12649        }
12650    }
12651
12652    @Override
12653    public void setRenderThread(int tid) {
12654        synchronized (this) {
12655            ProcessRecord proc;
12656            synchronized (mPidsSelfLocked) {
12657                int pid = Binder.getCallingPid();
12658                proc = mPidsSelfLocked.get(pid);
12659                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12660                    // ensure the tid belongs to the process
12661                    if (!Process.isThreadInProcess(pid, tid)) {
12662                        throw new IllegalArgumentException(
12663                            "Render thread does not belong to process");
12664                    }
12665                    proc.renderThreadTid = tid;
12666                    if (DEBUG_OOM_ADJ) {
12667                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12668                    }
12669                    // promote to FIFO now
12670                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12671                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12672                        if (mUseFifoUiScheduling) {
12673                            Process.setThreadScheduler(proc.renderThreadTid,
12674                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12675                        } else {
12676                            Process.setThreadPriority(proc.renderThreadTid, -10);
12677                        }
12678                    }
12679                } else {
12680                    if (DEBUG_OOM_ADJ) {
12681                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12682                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12683                               mUseFifoUiScheduling);
12684                    }
12685                }
12686            }
12687        }
12688    }
12689
12690    @Override
12691    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12692        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12693            throw new UnsupportedOperationException("VR mode not supported on this device!");
12694        }
12695
12696        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12697
12698        ActivityRecord r;
12699        synchronized (this) {
12700            r = ActivityRecord.isInStackLocked(token);
12701        }
12702
12703        if (r == null) {
12704            throw new IllegalArgumentException();
12705        }
12706
12707        int err;
12708        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12709                VrManagerInternal.NO_ERROR) {
12710            return err;
12711        }
12712
12713        synchronized(this) {
12714            r.requestedVrComponent = (enabled) ? packageName : null;
12715
12716            // Update associated state if this activity is currently focused
12717            if (r == mStackSupervisor.getResumedActivityLocked()) {
12718                applyUpdateVrModeLocked(r);
12719            }
12720            return 0;
12721        }
12722    }
12723
12724    @Override
12725    public boolean isVrModePackageEnabled(ComponentName packageName) {
12726        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12727            throw new UnsupportedOperationException("VR mode not supported on this device!");
12728        }
12729
12730        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12731
12732        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12733                VrManagerInternal.NO_ERROR;
12734    }
12735
12736    public boolean isTopActivityImmersive() {
12737        enforceNotIsolatedCaller("startActivity");
12738        synchronized (this) {
12739            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12740            return (r != null) ? r.immersive : false;
12741        }
12742    }
12743
12744    @Override
12745    public boolean isTopOfTask(IBinder token) {
12746        synchronized (this) {
12747            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12748            if (r == null) {
12749                throw new IllegalArgumentException();
12750            }
12751            return r.task.getTopActivity() == r;
12752        }
12753    }
12754
12755    @Override
12756    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12757        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12758            String msg = "Permission Denial: setHasTopUi() from pid="
12759                    + Binder.getCallingPid()
12760                    + ", uid=" + Binder.getCallingUid()
12761                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12762            Slog.w(TAG, msg);
12763            throw new SecurityException(msg);
12764        }
12765        final int pid = Binder.getCallingPid();
12766        final long origId = Binder.clearCallingIdentity();
12767        try {
12768            synchronized (this) {
12769                boolean changed = false;
12770                ProcessRecord pr;
12771                synchronized (mPidsSelfLocked) {
12772                    pr = mPidsSelfLocked.get(pid);
12773                    if (pr == null) {
12774                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12775                        return;
12776                    }
12777                    if (pr.hasTopUi != hasTopUi) {
12778                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12779                        pr.hasTopUi = hasTopUi;
12780                        changed = true;
12781                    }
12782                }
12783                if (changed) {
12784                    updateOomAdjLocked(pr);
12785                }
12786            }
12787        } finally {
12788            Binder.restoreCallingIdentity(origId);
12789        }
12790    }
12791
12792    public final void enterSafeMode() {
12793        synchronized(this) {
12794            // It only makes sense to do this before the system is ready
12795            // and started launching other packages.
12796            if (!mSystemReady) {
12797                try {
12798                    AppGlobals.getPackageManager().enterSafeMode();
12799                } catch (RemoteException e) {
12800                }
12801            }
12802
12803            mSafeMode = true;
12804        }
12805    }
12806
12807    public final void showSafeModeOverlay() {
12808        View v = LayoutInflater.from(mContext).inflate(
12809                com.android.internal.R.layout.safe_mode, null);
12810        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12811        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12812        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12813        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12814        lp.gravity = Gravity.BOTTOM | Gravity.START;
12815        lp.format = v.getBackground().getOpacity();
12816        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12817                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12818        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12819        ((WindowManager)mContext.getSystemService(
12820                Context.WINDOW_SERVICE)).addView(v, lp);
12821    }
12822
12823    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12824        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12825            return;
12826        }
12827        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12828        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12829        synchronized (stats) {
12830            if (mBatteryStatsService.isOnBattery()) {
12831                mBatteryStatsService.enforceCallingPermission();
12832                int MY_UID = Binder.getCallingUid();
12833                final int uid;
12834                if (sender == null) {
12835                    uid = sourceUid;
12836                } else {
12837                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12838                }
12839                BatteryStatsImpl.Uid.Pkg pkg =
12840                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12841                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12842                pkg.noteWakeupAlarmLocked(tag);
12843            }
12844        }
12845    }
12846
12847    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12848        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12849            return;
12850        }
12851        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12852        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12853        synchronized (stats) {
12854            mBatteryStatsService.enforceCallingPermission();
12855            int MY_UID = Binder.getCallingUid();
12856            final int uid;
12857            if (sender == null) {
12858                uid = sourceUid;
12859            } else {
12860                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12861            }
12862            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12863        }
12864    }
12865
12866    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12867        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12868            return;
12869        }
12870        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12871        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12872        synchronized (stats) {
12873            mBatteryStatsService.enforceCallingPermission();
12874            int MY_UID = Binder.getCallingUid();
12875            final int uid;
12876            if (sender == null) {
12877                uid = sourceUid;
12878            } else {
12879                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12880            }
12881            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12882        }
12883    }
12884
12885    public boolean killPids(int[] pids, String pReason, boolean secure) {
12886        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12887            throw new SecurityException("killPids only available to the system");
12888        }
12889        String reason = (pReason == null) ? "Unknown" : pReason;
12890        // XXX Note: don't acquire main activity lock here, because the window
12891        // manager calls in with its locks held.
12892
12893        boolean killed = false;
12894        synchronized (mPidsSelfLocked) {
12895            int worstType = 0;
12896            for (int i=0; i<pids.length; i++) {
12897                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12898                if (proc != null) {
12899                    int type = proc.setAdj;
12900                    if (type > worstType) {
12901                        worstType = type;
12902                    }
12903                }
12904            }
12905
12906            // If the worst oom_adj is somewhere in the cached proc LRU range,
12907            // then constrain it so we will kill all cached procs.
12908            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12909                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12910                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12911            }
12912
12913            // If this is not a secure call, don't let it kill processes that
12914            // are important.
12915            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12916                worstType = ProcessList.SERVICE_ADJ;
12917            }
12918
12919            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12920            for (int i=0; i<pids.length; i++) {
12921                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12922                if (proc == null) {
12923                    continue;
12924                }
12925                int adj = proc.setAdj;
12926                if (adj >= worstType && !proc.killedByAm) {
12927                    proc.kill(reason, true);
12928                    killed = true;
12929                }
12930            }
12931        }
12932        return killed;
12933    }
12934
12935    @Override
12936    public void killUid(int appId, int userId, String reason) {
12937        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12938        synchronized (this) {
12939            final long identity = Binder.clearCallingIdentity();
12940            try {
12941                killPackageProcessesLocked(null, appId, userId,
12942                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12943                        reason != null ? reason : "kill uid");
12944            } finally {
12945                Binder.restoreCallingIdentity(identity);
12946            }
12947        }
12948    }
12949
12950    @Override
12951    public boolean killProcessesBelowForeground(String reason) {
12952        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12953            throw new SecurityException("killProcessesBelowForeground() only available to system");
12954        }
12955
12956        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12957    }
12958
12959    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12960        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12961            throw new SecurityException("killProcessesBelowAdj() only available to system");
12962        }
12963
12964        boolean killed = false;
12965        synchronized (mPidsSelfLocked) {
12966            final int size = mPidsSelfLocked.size();
12967            for (int i = 0; i < size; i++) {
12968                final int pid = mPidsSelfLocked.keyAt(i);
12969                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12970                if (proc == null) continue;
12971
12972                final int adj = proc.setAdj;
12973                if (adj > belowAdj && !proc.killedByAm) {
12974                    proc.kill(reason, true);
12975                    killed = true;
12976                }
12977            }
12978        }
12979        return killed;
12980    }
12981
12982    @Override
12983    public void hang(final IBinder who, boolean allowRestart) {
12984        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12985                != PackageManager.PERMISSION_GRANTED) {
12986            throw new SecurityException("Requires permission "
12987                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12988        }
12989
12990        final IBinder.DeathRecipient death = new DeathRecipient() {
12991            @Override
12992            public void binderDied() {
12993                synchronized (this) {
12994                    notifyAll();
12995                }
12996            }
12997        };
12998
12999        try {
13000            who.linkToDeath(death, 0);
13001        } catch (RemoteException e) {
13002            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13003            return;
13004        }
13005
13006        synchronized (this) {
13007            Watchdog.getInstance().setAllowRestart(allowRestart);
13008            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13009            synchronized (death) {
13010                while (who.isBinderAlive()) {
13011                    try {
13012                        death.wait();
13013                    } catch (InterruptedException e) {
13014                    }
13015                }
13016            }
13017            Watchdog.getInstance().setAllowRestart(true);
13018        }
13019    }
13020
13021    @Override
13022    public void restart() {
13023        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13024                != PackageManager.PERMISSION_GRANTED) {
13025            throw new SecurityException("Requires permission "
13026                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13027        }
13028
13029        Log.i(TAG, "Sending shutdown broadcast...");
13030
13031        BroadcastReceiver br = new BroadcastReceiver() {
13032            @Override public void onReceive(Context context, Intent intent) {
13033                // Now the broadcast is done, finish up the low-level shutdown.
13034                Log.i(TAG, "Shutting down activity manager...");
13035                shutdown(10000);
13036                Log.i(TAG, "Shutdown complete, restarting!");
13037                Process.killProcess(Process.myPid());
13038                System.exit(10);
13039            }
13040        };
13041
13042        // First send the high-level shut down broadcast.
13043        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13044        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13045        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13046        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13047        mContext.sendOrderedBroadcastAsUser(intent,
13048                UserHandle.ALL, null, br, mHandler, 0, null, null);
13049        */
13050        br.onReceive(mContext, intent);
13051    }
13052
13053    private long getLowRamTimeSinceIdle(long now) {
13054        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13055    }
13056
13057    @Override
13058    public void performIdleMaintenance() {
13059        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13060                != PackageManager.PERMISSION_GRANTED) {
13061            throw new SecurityException("Requires permission "
13062                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13063        }
13064
13065        synchronized (this) {
13066            final long now = SystemClock.uptimeMillis();
13067            final long timeSinceLastIdle = now - mLastIdleTime;
13068            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13069            mLastIdleTime = now;
13070            mLowRamTimeSinceLastIdle = 0;
13071            if (mLowRamStartTime != 0) {
13072                mLowRamStartTime = now;
13073            }
13074
13075            StringBuilder sb = new StringBuilder(128);
13076            sb.append("Idle maintenance over ");
13077            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13078            sb.append(" low RAM for ");
13079            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13080            Slog.i(TAG, sb.toString());
13081
13082            // If at least 1/3 of our time since the last idle period has been spent
13083            // with RAM low, then we want to kill processes.
13084            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13085
13086            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13087                ProcessRecord proc = mLruProcesses.get(i);
13088                if (proc.notCachedSinceIdle) {
13089                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13090                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13091                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13092                        if (doKilling && proc.initialIdlePss != 0
13093                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13094                            sb = new StringBuilder(128);
13095                            sb.append("Kill");
13096                            sb.append(proc.processName);
13097                            sb.append(" in idle maint: pss=");
13098                            sb.append(proc.lastPss);
13099                            sb.append(", swapPss=");
13100                            sb.append(proc.lastSwapPss);
13101                            sb.append(", initialPss=");
13102                            sb.append(proc.initialIdlePss);
13103                            sb.append(", period=");
13104                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13105                            sb.append(", lowRamPeriod=");
13106                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13107                            Slog.wtfQuiet(TAG, sb.toString());
13108                            proc.kill("idle maint (pss " + proc.lastPss
13109                                    + " from " + proc.initialIdlePss + ")", true);
13110                        }
13111                    }
13112                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13113                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13114                    proc.notCachedSinceIdle = true;
13115                    proc.initialIdlePss = 0;
13116                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13117                            mTestPssMode, isSleepingLocked(), now);
13118                }
13119            }
13120
13121            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13122            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13123        }
13124    }
13125
13126    @Override
13127    public void sendIdleJobTrigger() {
13128        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13129                != PackageManager.PERMISSION_GRANTED) {
13130            throw new SecurityException("Requires permission "
13131                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13132        }
13133
13134        final long ident = Binder.clearCallingIdentity();
13135        try {
13136            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13137                    .setPackage("android")
13138                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13139            broadcastIntent(null, intent, null, null, 0, null, null, null,
13140                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13141        } finally {
13142            Binder.restoreCallingIdentity(ident);
13143        }
13144    }
13145
13146    private void retrieveSettings() {
13147        final ContentResolver resolver = mContext.getContentResolver();
13148        final boolean freeformWindowManagement =
13149                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13150                        || Settings.Global.getInt(
13151                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13152        final boolean supportsPictureInPicture =
13153                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13154
13155        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13156        final boolean supportsSplitScreenMultiWindow =
13157                ActivityManager.supportsSplitScreenMultiWindow();
13158        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13159        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13160        final boolean alwaysFinishActivities =
13161                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13162        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13163        final boolean forceResizable = Settings.Global.getInt(
13164                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13165        final boolean supportsLeanbackOnly =
13166                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13167
13168        // Transfer any global setting for forcing RTL layout, into a System Property
13169        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13170
13171        final Configuration configuration = new Configuration();
13172        Settings.System.getConfiguration(resolver, configuration);
13173        if (forceRtl) {
13174            // This will take care of setting the correct layout direction flags
13175            configuration.setLayoutDirection(configuration.locale);
13176        }
13177
13178        synchronized (this) {
13179            mDebugApp = mOrigDebugApp = debugApp;
13180            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13181            mAlwaysFinishActivities = alwaysFinishActivities;
13182            mSupportsLeanbackOnly = supportsLeanbackOnly;
13183            mForceResizableActivities = forceResizable;
13184            if (supportsMultiWindow || forceResizable) {
13185                mSupportsMultiWindow = true;
13186                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13187                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13188            } else {
13189                mSupportsMultiWindow = false;
13190                mSupportsFreeformWindowManagement = false;
13191                mSupportsPictureInPicture = false;
13192            }
13193            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13194            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13195            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13196            // This happens before any activities are started, so we can change global configuration
13197            // in-place.
13198            updateConfigurationLocked(configuration, null, true);
13199            final Configuration globalConfig = getGlobalConfiguration();
13200            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13201
13202            // Load resources only after the current configuration has been set.
13203            final Resources res = mContext.getResources();
13204            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13205            mThumbnailWidth = res.getDimensionPixelSize(
13206                    com.android.internal.R.dimen.thumbnail_width);
13207            mThumbnailHeight = res.getDimensionPixelSize(
13208                    com.android.internal.R.dimen.thumbnail_height);
13209            mMinPipAspectRatio = res.getFloat(
13210                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
13211            mMaxPipAspectRatio = res.getFloat(
13212                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
13213            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13214                    com.android.internal.R.string.config_appsNotReportingCrashes));
13215            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13216                    com.android.internal.R.bool.config_customUserSwitchUi);
13217            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13218                mFullscreenThumbnailScale = (float) res
13219                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13220                    (float) globalConfig.screenWidthDp;
13221            } else {
13222                mFullscreenThumbnailScale = res.getFraction(
13223                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13224            }
13225        }
13226    }
13227
13228    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13229        traceLog.traceBegin("PhaseActivityManagerReady");
13230        synchronized(this) {
13231            if (mSystemReady) {
13232                // If we're done calling all the receivers, run the next "boot phase" passed in
13233                // by the SystemServer
13234                if (goingCallback != null) {
13235                    goingCallback.run();
13236                }
13237                return;
13238            }
13239
13240            mLocalDeviceIdleController
13241                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13242
13243            // Make sure we have the current profile info, since it is needed for security checks.
13244            mUserController.onSystemReady();
13245            mRecentTasks.onSystemReadyLocked();
13246            mAppOpsService.systemReady();
13247            mSystemReady = true;
13248        }
13249
13250        ArrayList<ProcessRecord> procsToKill = null;
13251        synchronized(mPidsSelfLocked) {
13252            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13253                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13254                if (!isAllowedWhileBooting(proc.info)){
13255                    if (procsToKill == null) {
13256                        procsToKill = new ArrayList<ProcessRecord>();
13257                    }
13258                    procsToKill.add(proc);
13259                }
13260            }
13261        }
13262
13263        synchronized(this) {
13264            if (procsToKill != null) {
13265                for (int i=procsToKill.size()-1; i>=0; i--) {
13266                    ProcessRecord proc = procsToKill.get(i);
13267                    Slog.i(TAG, "Removing system update proc: " + proc);
13268                    removeProcessLocked(proc, true, false, "system update done");
13269                }
13270            }
13271
13272            // Now that we have cleaned up any update processes, we
13273            // are ready to start launching real processes and know that
13274            // we won't trample on them any more.
13275            mProcessesReady = true;
13276        }
13277
13278        Slog.i(TAG, "System now ready");
13279        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13280            SystemClock.uptimeMillis());
13281
13282        synchronized(this) {
13283            // Make sure we have no pre-ready processes sitting around.
13284
13285            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13286                ResolveInfo ri = mContext.getPackageManager()
13287                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13288                                STOCK_PM_FLAGS);
13289                CharSequence errorMsg = null;
13290                if (ri != null) {
13291                    ActivityInfo ai = ri.activityInfo;
13292                    ApplicationInfo app = ai.applicationInfo;
13293                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13294                        mTopAction = Intent.ACTION_FACTORY_TEST;
13295                        mTopData = null;
13296                        mTopComponent = new ComponentName(app.packageName,
13297                                ai.name);
13298                    } else {
13299                        errorMsg = mContext.getResources().getText(
13300                                com.android.internal.R.string.factorytest_not_system);
13301                    }
13302                } else {
13303                    errorMsg = mContext.getResources().getText(
13304                            com.android.internal.R.string.factorytest_no_action);
13305                }
13306                if (errorMsg != null) {
13307                    mTopAction = null;
13308                    mTopData = null;
13309                    mTopComponent = null;
13310                    Message msg = Message.obtain();
13311                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13312                    msg.getData().putCharSequence("msg", errorMsg);
13313                    mUiHandler.sendMessage(msg);
13314                }
13315            }
13316        }
13317
13318        retrieveSettings();
13319        final int currentUserId;
13320        synchronized (this) {
13321            currentUserId = mUserController.getCurrentUserIdLocked();
13322            readGrantedUriPermissionsLocked();
13323        }
13324
13325        if (goingCallback != null) goingCallback.run();
13326        traceLog.traceBegin("ActivityManagerStartApps");
13327        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13328                Integer.toString(currentUserId), currentUserId);
13329        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13330                Integer.toString(currentUserId), currentUserId);
13331        mSystemServiceManager.startUser(currentUserId);
13332
13333        synchronized (this) {
13334            // Only start up encryption-aware persistent apps; once user is
13335            // unlocked we'll come back around and start unaware apps
13336            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13337
13338            // Start up initial activity.
13339            mBooting = true;
13340            // Enable home activity for system user, so that the system can always boot. We don't
13341            // do this when the system user is not setup since the setup wizard should be the one
13342            // to handle home activity in this case.
13343            if (UserManager.isSplitSystemUser() &&
13344                    Settings.Secure.getInt(mContext.getContentResolver(),
13345                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13346                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13347                try {
13348                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13349                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13350                            UserHandle.USER_SYSTEM);
13351                } catch (RemoteException e) {
13352                    throw e.rethrowAsRuntimeException();
13353                }
13354            }
13355            startHomeActivityLocked(currentUserId, "systemReady");
13356
13357            try {
13358                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13359                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13360                            + " data partition or your device will be unstable.");
13361                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13362                }
13363            } catch (RemoteException e) {
13364            }
13365
13366            if (!Build.isBuildConsistent()) {
13367                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13368                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13369            }
13370
13371            long ident = Binder.clearCallingIdentity();
13372            try {
13373                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13374                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13375                        | Intent.FLAG_RECEIVER_FOREGROUND);
13376                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13377                broadcastIntentLocked(null, null, intent,
13378                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13379                        null, false, false, MY_PID, Process.SYSTEM_UID,
13380                        currentUserId);
13381                intent = new Intent(Intent.ACTION_USER_STARTING);
13382                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13383                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13384                broadcastIntentLocked(null, null, intent,
13385                        null, new IIntentReceiver.Stub() {
13386                            @Override
13387                            public void performReceive(Intent intent, int resultCode, String data,
13388                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13389                                    throws RemoteException {
13390                            }
13391                        }, 0, null, null,
13392                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13393                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13394            } catch (Throwable t) {
13395                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13396            } finally {
13397                Binder.restoreCallingIdentity(ident);
13398            }
13399            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13400            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13401            traceLog.traceEnd(); // ActivityManagerStartApps
13402            traceLog.traceEnd(); // PhaseActivityManagerReady
13403        }
13404    }
13405
13406    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13407        synchronized (this) {
13408            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13409        }
13410    }
13411
13412    void skipCurrentReceiverLocked(ProcessRecord app) {
13413        for (BroadcastQueue queue : mBroadcastQueues) {
13414            queue.skipCurrentReceiverLocked(app);
13415        }
13416    }
13417
13418    /**
13419     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13420     * The application process will exit immediately after this call returns.
13421     * @param app object of the crashing app, null for the system server
13422     * @param crashInfo describing the exception
13423     */
13424    public void handleApplicationCrash(IBinder app,
13425            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13426        ProcessRecord r = findAppProcess(app, "Crash");
13427        final String processName = app == null ? "system_server"
13428                : (r == null ? "unknown" : r.processName);
13429
13430        handleApplicationCrashInner("crash", r, processName, crashInfo);
13431    }
13432
13433    /* Native crash reporting uses this inner version because it needs to be somewhat
13434     * decoupled from the AM-managed cleanup lifecycle
13435     */
13436    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13437            ApplicationErrorReport.CrashInfo crashInfo) {
13438        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13439                UserHandle.getUserId(Binder.getCallingUid()), processName,
13440                r == null ? -1 : r.info.flags,
13441                crashInfo.exceptionClassName,
13442                crashInfo.exceptionMessage,
13443                crashInfo.throwFileName,
13444                crashInfo.throwLineNumber);
13445
13446        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13447
13448        mAppErrors.crashApplication(r, crashInfo);
13449    }
13450
13451    public void handleApplicationStrictModeViolation(
13452            IBinder app,
13453            int violationMask,
13454            StrictMode.ViolationInfo info) {
13455        ProcessRecord r = findAppProcess(app, "StrictMode");
13456        if (r == null) {
13457            return;
13458        }
13459
13460        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13461            Integer stackFingerprint = info.hashCode();
13462            boolean logIt = true;
13463            synchronized (mAlreadyLoggedViolatedStacks) {
13464                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13465                    logIt = false;
13466                    // TODO: sub-sample into EventLog for these, with
13467                    // the info.durationMillis?  Then we'd get
13468                    // the relative pain numbers, without logging all
13469                    // the stack traces repeatedly.  We'd want to do
13470                    // likewise in the client code, which also does
13471                    // dup suppression, before the Binder call.
13472                } else {
13473                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13474                        mAlreadyLoggedViolatedStacks.clear();
13475                    }
13476                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13477                }
13478            }
13479            if (logIt) {
13480                logStrictModeViolationToDropBox(r, info);
13481            }
13482        }
13483
13484        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13485            AppErrorResult result = new AppErrorResult();
13486            synchronized (this) {
13487                final long origId = Binder.clearCallingIdentity();
13488
13489                Message msg = Message.obtain();
13490                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13491                HashMap<String, Object> data = new HashMap<String, Object>();
13492                data.put("result", result);
13493                data.put("app", r);
13494                data.put("violationMask", violationMask);
13495                data.put("info", info);
13496                msg.obj = data;
13497                mUiHandler.sendMessage(msg);
13498
13499                Binder.restoreCallingIdentity(origId);
13500            }
13501            int res = result.get();
13502            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13503        }
13504    }
13505
13506    // Depending on the policy in effect, there could be a bunch of
13507    // these in quick succession so we try to batch these together to
13508    // minimize disk writes, number of dropbox entries, and maximize
13509    // compression, by having more fewer, larger records.
13510    private void logStrictModeViolationToDropBox(
13511            ProcessRecord process,
13512            StrictMode.ViolationInfo info) {
13513        if (info == null) {
13514            return;
13515        }
13516        final boolean isSystemApp = process == null ||
13517                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13518                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13519        final String processName = process == null ? "unknown" : process.processName;
13520        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13521        final DropBoxManager dbox = (DropBoxManager)
13522                mContext.getSystemService(Context.DROPBOX_SERVICE);
13523
13524        // Exit early if the dropbox isn't configured to accept this report type.
13525        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13526
13527        boolean bufferWasEmpty;
13528        boolean needsFlush;
13529        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13530        synchronized (sb) {
13531            bufferWasEmpty = sb.length() == 0;
13532            appendDropBoxProcessHeaders(process, processName, sb);
13533            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13534            sb.append("System-App: ").append(isSystemApp).append("\n");
13535            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13536            if (info.violationNumThisLoop != 0) {
13537                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13538            }
13539            if (info.numAnimationsRunning != 0) {
13540                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13541            }
13542            if (info.broadcastIntentAction != null) {
13543                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13544            }
13545            if (info.durationMillis != -1) {
13546                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13547            }
13548            if (info.numInstances != -1) {
13549                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13550            }
13551            if (info.tags != null) {
13552                for (String tag : info.tags) {
13553                    sb.append("Span-Tag: ").append(tag).append("\n");
13554                }
13555            }
13556            sb.append("\n");
13557            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13558                sb.append(info.crashInfo.stackTrace);
13559                sb.append("\n");
13560            }
13561            if (info.message != null) {
13562                sb.append(info.message);
13563                sb.append("\n");
13564            }
13565
13566            // Only buffer up to ~64k.  Various logging bits truncate
13567            // things at 128k.
13568            needsFlush = (sb.length() > 64 * 1024);
13569        }
13570
13571        // Flush immediately if the buffer's grown too large, or this
13572        // is a non-system app.  Non-system apps are isolated with a
13573        // different tag & policy and not batched.
13574        //
13575        // Batching is useful during internal testing with
13576        // StrictMode settings turned up high.  Without batching,
13577        // thousands of separate files could be created on boot.
13578        if (!isSystemApp || needsFlush) {
13579            new Thread("Error dump: " + dropboxTag) {
13580                @Override
13581                public void run() {
13582                    String report;
13583                    synchronized (sb) {
13584                        report = sb.toString();
13585                        sb.delete(0, sb.length());
13586                        sb.trimToSize();
13587                    }
13588                    if (report.length() != 0) {
13589                        dbox.addText(dropboxTag, report);
13590                    }
13591                }
13592            }.start();
13593            return;
13594        }
13595
13596        // System app batching:
13597        if (!bufferWasEmpty) {
13598            // An existing dropbox-writing thread is outstanding, so
13599            // we don't need to start it up.  The existing thread will
13600            // catch the buffer appends we just did.
13601            return;
13602        }
13603
13604        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13605        // (After this point, we shouldn't access AMS internal data structures.)
13606        new Thread("Error dump: " + dropboxTag) {
13607            @Override
13608            public void run() {
13609                // 5 second sleep to let stacks arrive and be batched together
13610                try {
13611                    Thread.sleep(5000);  // 5 seconds
13612                } catch (InterruptedException e) {}
13613
13614                String errorReport;
13615                synchronized (mStrictModeBuffer) {
13616                    errorReport = mStrictModeBuffer.toString();
13617                    if (errorReport.length() == 0) {
13618                        return;
13619                    }
13620                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13621                    mStrictModeBuffer.trimToSize();
13622                }
13623                dbox.addText(dropboxTag, errorReport);
13624            }
13625        }.start();
13626    }
13627
13628    /**
13629     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13630     * @param app object of the crashing app, null for the system server
13631     * @param tag reported by the caller
13632     * @param system whether this wtf is coming from the system
13633     * @param crashInfo describing the context of the error
13634     * @return true if the process should exit immediately (WTF is fatal)
13635     */
13636    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13637            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13638        final int callingUid = Binder.getCallingUid();
13639        final int callingPid = Binder.getCallingPid();
13640
13641        if (system) {
13642            // If this is coming from the system, we could very well have low-level
13643            // system locks held, so we want to do this all asynchronously.  And we
13644            // never want this to become fatal, so there is that too.
13645            mHandler.post(new Runnable() {
13646                @Override public void run() {
13647                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13648                }
13649            });
13650            return false;
13651        }
13652
13653        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13654                crashInfo);
13655
13656        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
13657                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
13658        final boolean isSystem = (r == null) || r.persistent;
13659
13660        if (isFatal && !isSystem) {
13661            mAppErrors.crashApplication(r, crashInfo);
13662            return true;
13663        } else {
13664            return false;
13665        }
13666    }
13667
13668    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13669            final ApplicationErrorReport.CrashInfo crashInfo) {
13670        final ProcessRecord r = findAppProcess(app, "WTF");
13671        final String processName = app == null ? "system_server"
13672                : (r == null ? "unknown" : r.processName);
13673
13674        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13675                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13676
13677        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13678
13679        return r;
13680    }
13681
13682    /**
13683     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13684     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13685     */
13686    private ProcessRecord findAppProcess(IBinder app, String reason) {
13687        if (app == null) {
13688            return null;
13689        }
13690
13691        synchronized (this) {
13692            final int NP = mProcessNames.getMap().size();
13693            for (int ip=0; ip<NP; ip++) {
13694                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13695                final int NA = apps.size();
13696                for (int ia=0; ia<NA; ia++) {
13697                    ProcessRecord p = apps.valueAt(ia);
13698                    if (p.thread != null && p.thread.asBinder() == app) {
13699                        return p;
13700                    }
13701                }
13702            }
13703
13704            Slog.w(TAG, "Can't find mystery application for " + reason
13705                    + " from pid=" + Binder.getCallingPid()
13706                    + " uid=" + Binder.getCallingUid() + ": " + app);
13707            return null;
13708        }
13709    }
13710
13711    /**
13712     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13713     * to append various headers to the dropbox log text.
13714     */
13715    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13716            StringBuilder sb) {
13717        // Watchdog thread ends up invoking this function (with
13718        // a null ProcessRecord) to add the stack file to dropbox.
13719        // Do not acquire a lock on this (am) in such cases, as it
13720        // could cause a potential deadlock, if and when watchdog
13721        // is invoked due to unavailability of lock on am and it
13722        // would prevent watchdog from killing system_server.
13723        if (process == null) {
13724            sb.append("Process: ").append(processName).append("\n");
13725            return;
13726        }
13727        // Note: ProcessRecord 'process' is guarded by the service
13728        // instance.  (notably process.pkgList, which could otherwise change
13729        // concurrently during execution of this method)
13730        synchronized (this) {
13731            sb.append("Process: ").append(processName).append("\n");
13732            int flags = process.info.flags;
13733            IPackageManager pm = AppGlobals.getPackageManager();
13734            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13735            for (int ip=0; ip<process.pkgList.size(); ip++) {
13736                String pkg = process.pkgList.keyAt(ip);
13737                sb.append("Package: ").append(pkg);
13738                try {
13739                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13740                    if (pi != null) {
13741                        sb.append(" v").append(pi.versionCode);
13742                        if (pi.versionName != null) {
13743                            sb.append(" (").append(pi.versionName).append(")");
13744                        }
13745                    }
13746                } catch (RemoteException e) {
13747                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13748                }
13749                sb.append("\n");
13750            }
13751        }
13752    }
13753
13754    private static String processClass(ProcessRecord process) {
13755        if (process == null || process.pid == MY_PID) {
13756            return "system_server";
13757        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13758            return "system_app";
13759        } else {
13760            return "data_app";
13761        }
13762    }
13763
13764    private volatile long mWtfClusterStart;
13765    private volatile int mWtfClusterCount;
13766
13767    /**
13768     * Write a description of an error (crash, WTF, ANR) to the drop box.
13769     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13770     * @param process which caused the error, null means the system server
13771     * @param activity which triggered the error, null if unknown
13772     * @param parent activity related to the error, null if unknown
13773     * @param subject line related to the error, null if absent
13774     * @param report in long form describing the error, null if absent
13775     * @param dataFile text file to include in the report, null if none
13776     * @param crashInfo giving an application stack trace, null if absent
13777     */
13778    public void addErrorToDropBox(String eventType,
13779            ProcessRecord process, String processName, ActivityRecord activity,
13780            ActivityRecord parent, String subject,
13781            final String report, final File dataFile,
13782            final ApplicationErrorReport.CrashInfo crashInfo) {
13783        // NOTE -- this must never acquire the ActivityManagerService lock,
13784        // otherwise the watchdog may be prevented from resetting the system.
13785
13786        // Bail early if not published yet
13787        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13788        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13789
13790        // Exit early if the dropbox isn't configured to accept this report type.
13791        final String dropboxTag = processClass(process) + "_" + eventType;
13792        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13793
13794        // Rate-limit how often we're willing to do the heavy lifting below to
13795        // collect and record logs; currently 5 logs per 10 second period.
13796        final long now = SystemClock.elapsedRealtime();
13797        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13798            mWtfClusterStart = now;
13799            mWtfClusterCount = 1;
13800        } else {
13801            if (mWtfClusterCount++ >= 5) return;
13802        }
13803
13804        final StringBuilder sb = new StringBuilder(1024);
13805        appendDropBoxProcessHeaders(process, processName, sb);
13806        if (process != null) {
13807            sb.append("Foreground: ")
13808                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13809                    .append("\n");
13810        }
13811        if (activity != null) {
13812            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13813        }
13814        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13815            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13816        }
13817        if (parent != null && parent != activity) {
13818            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13819        }
13820        if (subject != null) {
13821            sb.append("Subject: ").append(subject).append("\n");
13822        }
13823        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13824        if (Debug.isDebuggerConnected()) {
13825            sb.append("Debugger: Connected\n");
13826        }
13827        sb.append("\n");
13828
13829        // Do the rest in a worker thread to avoid blocking the caller on I/O
13830        // (After this point, we shouldn't access AMS internal data structures.)
13831        Thread worker = new Thread("Error dump: " + dropboxTag) {
13832            @Override
13833            public void run() {
13834                if (report != null) {
13835                    sb.append(report);
13836                }
13837
13838                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13839                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13840                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13841                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13842
13843                if (dataFile != null && maxDataFileSize > 0) {
13844                    try {
13845                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13846                                    "\n\n[[TRUNCATED]]"));
13847                    } catch (IOException e) {
13848                        Slog.e(TAG, "Error reading " + dataFile, e);
13849                    }
13850                }
13851                if (crashInfo != null && crashInfo.stackTrace != null) {
13852                    sb.append(crashInfo.stackTrace);
13853                }
13854
13855                if (lines > 0) {
13856                    sb.append("\n");
13857
13858                    // Merge several logcat streams, and take the last N lines
13859                    InputStreamReader input = null;
13860                    try {
13861                        java.lang.Process logcat = new ProcessBuilder(
13862                                "/system/bin/timeout", "-k", "15s", "10s",
13863                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13864                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13865                                        .redirectErrorStream(true).start();
13866
13867                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13868                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13869                        input = new InputStreamReader(logcat.getInputStream());
13870
13871                        int num;
13872                        char[] buf = new char[8192];
13873                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13874                    } catch (IOException e) {
13875                        Slog.e(TAG, "Error running logcat", e);
13876                    } finally {
13877                        if (input != null) try { input.close(); } catch (IOException e) {}
13878                    }
13879                }
13880
13881                dbox.addText(dropboxTag, sb.toString());
13882            }
13883        };
13884
13885        if (process == null) {
13886            // If process is null, we are being called from some internal code
13887            // and may be about to die -- run this synchronously.
13888            worker.run();
13889        } else {
13890            worker.start();
13891        }
13892    }
13893
13894    @Override
13895    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13896        enforceNotIsolatedCaller("getProcessesInErrorState");
13897        // assume our apps are happy - lazy create the list
13898        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13899
13900        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13901                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13902        int userId = UserHandle.getUserId(Binder.getCallingUid());
13903
13904        synchronized (this) {
13905
13906            // iterate across all processes
13907            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13908                ProcessRecord app = mLruProcesses.get(i);
13909                if (!allUsers && app.userId != userId) {
13910                    continue;
13911                }
13912                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13913                    // This one's in trouble, so we'll generate a report for it
13914                    // crashes are higher priority (in case there's a crash *and* an anr)
13915                    ActivityManager.ProcessErrorStateInfo report = null;
13916                    if (app.crashing) {
13917                        report = app.crashingReport;
13918                    } else if (app.notResponding) {
13919                        report = app.notRespondingReport;
13920                    }
13921
13922                    if (report != null) {
13923                        if (errList == null) {
13924                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13925                        }
13926                        errList.add(report);
13927                    } else {
13928                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13929                                " crashing = " + app.crashing +
13930                                " notResponding = " + app.notResponding);
13931                    }
13932                }
13933            }
13934        }
13935
13936        return errList;
13937    }
13938
13939    static int procStateToImportance(int procState, int memAdj,
13940            ActivityManager.RunningAppProcessInfo currApp) {
13941        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13942        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13943            currApp.lru = memAdj;
13944        } else {
13945            currApp.lru = 0;
13946        }
13947        return imp;
13948    }
13949
13950    private void fillInProcMemInfo(ProcessRecord app,
13951            ActivityManager.RunningAppProcessInfo outInfo) {
13952        outInfo.pid = app.pid;
13953        outInfo.uid = app.info.uid;
13954        if (mHeavyWeightProcess == app) {
13955            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13956        }
13957        if (app.persistent) {
13958            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13959        }
13960        if (app.activities.size() > 0) {
13961            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13962        }
13963        outInfo.lastTrimLevel = app.trimMemoryLevel;
13964        int adj = app.curAdj;
13965        int procState = app.curProcState;
13966        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13967        outInfo.importanceReasonCode = app.adjTypeCode;
13968        outInfo.processState = app.curProcState;
13969    }
13970
13971    @Override
13972    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13973        enforceNotIsolatedCaller("getRunningAppProcesses");
13974
13975        final int callingUid = Binder.getCallingUid();
13976
13977        // Lazy instantiation of list
13978        List<ActivityManager.RunningAppProcessInfo> runList = null;
13979        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13980                callingUid) == PackageManager.PERMISSION_GRANTED;
13981        final int userId = UserHandle.getUserId(callingUid);
13982        final boolean allUids = isGetTasksAllowed(
13983                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13984
13985        synchronized (this) {
13986            // Iterate across all processes
13987            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13988                ProcessRecord app = mLruProcesses.get(i);
13989                if ((!allUsers && app.userId != userId)
13990                        || (!allUids && app.uid != callingUid)) {
13991                    continue;
13992                }
13993                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13994                    // Generate process state info for running application
13995                    ActivityManager.RunningAppProcessInfo currApp =
13996                        new ActivityManager.RunningAppProcessInfo(app.processName,
13997                                app.pid, app.getPackageList());
13998                    fillInProcMemInfo(app, currApp);
13999                    if (app.adjSource instanceof ProcessRecord) {
14000                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14001                        currApp.importanceReasonImportance =
14002                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14003                                        app.adjSourceProcState);
14004                    } else if (app.adjSource instanceof ActivityRecord) {
14005                        ActivityRecord r = (ActivityRecord)app.adjSource;
14006                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14007                    }
14008                    if (app.adjTarget instanceof ComponentName) {
14009                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14010                    }
14011                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14012                    //        + " lru=" + currApp.lru);
14013                    if (runList == null) {
14014                        runList = new ArrayList<>();
14015                    }
14016                    runList.add(currApp);
14017                }
14018            }
14019        }
14020        return runList;
14021    }
14022
14023    @Override
14024    public List<ApplicationInfo> getRunningExternalApplications() {
14025        enforceNotIsolatedCaller("getRunningExternalApplications");
14026        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14027        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14028        if (runningApps != null && runningApps.size() > 0) {
14029            Set<String> extList = new HashSet<String>();
14030            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14031                if (app.pkgList != null) {
14032                    for (String pkg : app.pkgList) {
14033                        extList.add(pkg);
14034                    }
14035                }
14036            }
14037            IPackageManager pm = AppGlobals.getPackageManager();
14038            for (String pkg : extList) {
14039                try {
14040                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14041                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14042                        retList.add(info);
14043                    }
14044                } catch (RemoteException e) {
14045                }
14046            }
14047        }
14048        return retList;
14049    }
14050
14051    @Override
14052    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14053        enforceNotIsolatedCaller("getMyMemoryState");
14054        synchronized (this) {
14055            ProcessRecord proc;
14056            synchronized (mPidsSelfLocked) {
14057                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14058            }
14059            fillInProcMemInfo(proc, outInfo);
14060        }
14061    }
14062
14063    @Override
14064    public int getMemoryTrimLevel() {
14065        enforceNotIsolatedCaller("getMyMemoryState");
14066        synchronized (this) {
14067            return mLastMemoryLevel;
14068        }
14069    }
14070
14071    @Override
14072    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14073            FileDescriptor err, String[] args, ShellCallback callback,
14074            ResultReceiver resultReceiver) {
14075        (new ActivityManagerShellCommand(this, false)).exec(
14076                this, in, out, err, args, callback, resultReceiver);
14077    }
14078
14079    @Override
14080    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14081        if (checkCallingPermission(android.Manifest.permission.DUMP)
14082                != PackageManager.PERMISSION_GRANTED) {
14083            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14084                    + Binder.getCallingPid()
14085                    + ", uid=" + Binder.getCallingUid()
14086                    + " without permission "
14087                    + android.Manifest.permission.DUMP);
14088            return;
14089        }
14090
14091        boolean dumpAll = false;
14092        boolean dumpClient = false;
14093        boolean dumpCheckin = false;
14094        boolean dumpCheckinFormat = false;
14095        boolean dumpVisibleStacks = false;
14096        String dumpPackage = null;
14097
14098        int opti = 0;
14099        while (opti < args.length) {
14100            String opt = args[opti];
14101            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14102                break;
14103            }
14104            opti++;
14105            if ("-a".equals(opt)) {
14106                dumpAll = true;
14107            } else if ("-c".equals(opt)) {
14108                dumpClient = true;
14109            } else if ("-v".equals(opt)) {
14110                dumpVisibleStacks = true;
14111            } else if ("-p".equals(opt)) {
14112                if (opti < args.length) {
14113                    dumpPackage = args[opti];
14114                    opti++;
14115                } else {
14116                    pw.println("Error: -p option requires package argument");
14117                    return;
14118                }
14119                dumpClient = true;
14120            } else if ("--checkin".equals(opt)) {
14121                dumpCheckin = dumpCheckinFormat = true;
14122            } else if ("-C".equals(opt)) {
14123                dumpCheckinFormat = true;
14124            } else if ("-h".equals(opt)) {
14125                ActivityManagerShellCommand.dumpHelp(pw, true);
14126                return;
14127            } else {
14128                pw.println("Unknown argument: " + opt + "; use -h for help");
14129            }
14130        }
14131
14132        long origId = Binder.clearCallingIdentity();
14133        boolean more = false;
14134        // Is the caller requesting to dump a particular piece of data?
14135        if (opti < args.length) {
14136            String cmd = args[opti];
14137            opti++;
14138            if ("activities".equals(cmd) || "a".equals(cmd)) {
14139                synchronized (this) {
14140                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14141                }
14142            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14143                synchronized (this) {
14144                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14145                }
14146            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14147                String[] newArgs;
14148                String name;
14149                if (opti >= args.length) {
14150                    name = null;
14151                    newArgs = EMPTY_STRING_ARRAY;
14152                } else {
14153                    dumpPackage = args[opti];
14154                    opti++;
14155                    newArgs = new String[args.length - opti];
14156                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14157                            args.length - opti);
14158                }
14159                synchronized (this) {
14160                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14161                }
14162            } else if ("broadcast-stats".equals(cmd)) {
14163                String[] newArgs;
14164                String name;
14165                if (opti >= args.length) {
14166                    name = null;
14167                    newArgs = EMPTY_STRING_ARRAY;
14168                } else {
14169                    dumpPackage = args[opti];
14170                    opti++;
14171                    newArgs = new String[args.length - opti];
14172                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14173                            args.length - opti);
14174                }
14175                synchronized (this) {
14176                    if (dumpCheckinFormat) {
14177                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14178                                dumpPackage);
14179                    } else {
14180                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14181                    }
14182                }
14183            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14184                String[] newArgs;
14185                String name;
14186                if (opti >= args.length) {
14187                    name = null;
14188                    newArgs = EMPTY_STRING_ARRAY;
14189                } else {
14190                    dumpPackage = args[opti];
14191                    opti++;
14192                    newArgs = new String[args.length - opti];
14193                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14194                            args.length - opti);
14195                }
14196                synchronized (this) {
14197                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14198                }
14199            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14200                String[] newArgs;
14201                String name;
14202                if (opti >= args.length) {
14203                    name = null;
14204                    newArgs = EMPTY_STRING_ARRAY;
14205                } else {
14206                    dumpPackage = args[opti];
14207                    opti++;
14208                    newArgs = new String[args.length - opti];
14209                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14210                            args.length - opti);
14211                }
14212                synchronized (this) {
14213                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14214                }
14215            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14216                synchronized (this) {
14217                    dumpOomLocked(fd, pw, args, opti, true);
14218                }
14219            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14220                synchronized (this) {
14221                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14222                }
14223            } else if ("provider".equals(cmd)) {
14224                String[] newArgs;
14225                String name;
14226                if (opti >= args.length) {
14227                    name = null;
14228                    newArgs = EMPTY_STRING_ARRAY;
14229                } else {
14230                    name = args[opti];
14231                    opti++;
14232                    newArgs = new String[args.length - opti];
14233                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14234                }
14235                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14236                    pw.println("No providers match: " + name);
14237                    pw.println("Use -h for help.");
14238                }
14239            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14240                synchronized (this) {
14241                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14242                }
14243            } else if ("service".equals(cmd)) {
14244                String[] newArgs;
14245                String name;
14246                if (opti >= args.length) {
14247                    name = null;
14248                    newArgs = EMPTY_STRING_ARRAY;
14249                } else {
14250                    name = args[opti];
14251                    opti++;
14252                    newArgs = new String[args.length - opti];
14253                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14254                            args.length - opti);
14255                }
14256                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14257                    pw.println("No services match: " + name);
14258                    pw.println("Use -h for help.");
14259                }
14260            } else if ("package".equals(cmd)) {
14261                String[] newArgs;
14262                if (opti >= args.length) {
14263                    pw.println("package: no package name specified");
14264                    pw.println("Use -h for help.");
14265                } else {
14266                    dumpPackage = args[opti];
14267                    opti++;
14268                    newArgs = new String[args.length - opti];
14269                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14270                            args.length - opti);
14271                    args = newArgs;
14272                    opti = 0;
14273                    more = true;
14274                }
14275            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14276                synchronized (this) {
14277                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14278                }
14279            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14280                if (dumpClient) {
14281                    ActiveServices.ServiceDumper dumper;
14282                    synchronized (this) {
14283                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14284                                dumpPackage);
14285                    }
14286                    dumper.dumpWithClient();
14287                } else {
14288                    synchronized (this) {
14289                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14290                                dumpPackage).dumpLocked();
14291                    }
14292                }
14293            } else if ("locks".equals(cmd)) {
14294                LockGuard.dump(fd, pw, args);
14295            } else {
14296                // Dumping a single activity?
14297                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14298                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14299                    int res = shell.exec(this, null, fd, null, args, null,
14300                            new ResultReceiver(null));
14301                    if (res < 0) {
14302                        pw.println("Bad activity command, or no activities match: " + cmd);
14303                        pw.println("Use -h for help.");
14304                    }
14305                }
14306            }
14307            if (!more) {
14308                Binder.restoreCallingIdentity(origId);
14309                return;
14310            }
14311        }
14312
14313        // No piece of data specified, dump everything.
14314        if (dumpCheckinFormat) {
14315            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14316        } else if (dumpClient) {
14317            ActiveServices.ServiceDumper sdumper;
14318            synchronized (this) {
14319                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14320                pw.println();
14321                if (dumpAll) {
14322                    pw.println("-------------------------------------------------------------------------------");
14323                }
14324                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14325                pw.println();
14326                if (dumpAll) {
14327                    pw.println("-------------------------------------------------------------------------------");
14328                }
14329                if (dumpAll || dumpPackage != null) {
14330                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14331                    pw.println();
14332                    if (dumpAll) {
14333                        pw.println("-------------------------------------------------------------------------------");
14334                    }
14335                }
14336                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14337                pw.println();
14338                if (dumpAll) {
14339                    pw.println("-------------------------------------------------------------------------------");
14340                }
14341                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14342                pw.println();
14343                if (dumpAll) {
14344                    pw.println("-------------------------------------------------------------------------------");
14345                }
14346                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14347                        dumpPackage);
14348            }
14349            sdumper.dumpWithClient();
14350            pw.println();
14351            synchronized (this) {
14352                if (dumpAll) {
14353                    pw.println("-------------------------------------------------------------------------------");
14354                }
14355                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14356                pw.println();
14357                if (dumpAll) {
14358                    pw.println("-------------------------------------------------------------------------------");
14359                }
14360                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14361                if (mAssociations.size() > 0) {
14362                    pw.println();
14363                    if (dumpAll) {
14364                        pw.println("-------------------------------------------------------------------------------");
14365                    }
14366                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14367                }
14368                pw.println();
14369                if (dumpAll) {
14370                    pw.println("-------------------------------------------------------------------------------");
14371                }
14372                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14373            }
14374
14375        } else {
14376            synchronized (this) {
14377                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14378                pw.println();
14379                if (dumpAll) {
14380                    pw.println("-------------------------------------------------------------------------------");
14381                }
14382                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14383                pw.println();
14384                if (dumpAll) {
14385                    pw.println("-------------------------------------------------------------------------------");
14386                }
14387                if (dumpAll || dumpPackage != null) {
14388                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14389                    pw.println();
14390                    if (dumpAll) {
14391                        pw.println("-------------------------------------------------------------------------------");
14392                    }
14393                }
14394                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14395                pw.println();
14396                if (dumpAll) {
14397                    pw.println("-------------------------------------------------------------------------------");
14398                }
14399                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14400                pw.println();
14401                if (dumpAll) {
14402                    pw.println("-------------------------------------------------------------------------------");
14403                }
14404                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14405                        .dumpLocked();
14406                pw.println();
14407                if (dumpAll) {
14408                    pw.println("-------------------------------------------------------------------------------");
14409                }
14410                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14411                pw.println();
14412                if (dumpAll) {
14413                    pw.println("-------------------------------------------------------------------------------");
14414                }
14415                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14416                if (mAssociations.size() > 0) {
14417                    pw.println();
14418                    if (dumpAll) {
14419                        pw.println("-------------------------------------------------------------------------------");
14420                    }
14421                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14422                }
14423                pw.println();
14424                if (dumpAll) {
14425                    pw.println("-------------------------------------------------------------------------------");
14426                }
14427                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14428            }
14429        }
14430        Binder.restoreCallingIdentity(origId);
14431    }
14432
14433    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14434            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14435        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14436
14437        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14438                dumpPackage);
14439        boolean needSep = printedAnything;
14440
14441        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14442                mStackSupervisor.getResumedActivityLocked(),
14443                dumpPackage, needSep, "  ResumedActivity: ");
14444        if (printed) {
14445            printedAnything = true;
14446            needSep = false;
14447        }
14448
14449        if (dumpPackage == null) {
14450            if (needSep) {
14451                pw.println();
14452            }
14453            needSep = true;
14454            printedAnything = true;
14455            mStackSupervisor.dump(pw, "  ");
14456        }
14457
14458        if (!printedAnything) {
14459            pw.println("  (nothing)");
14460        }
14461    }
14462
14463    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14464            int opti, boolean dumpAll, String dumpPackage) {
14465        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14466
14467        boolean printedAnything = false;
14468
14469        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14470            boolean printedHeader = false;
14471
14472            final int N = mRecentTasks.size();
14473            for (int i=0; i<N; i++) {
14474                TaskRecord tr = mRecentTasks.get(i);
14475                if (dumpPackage != null) {
14476                    if (tr.realActivity == null ||
14477                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14478                        continue;
14479                    }
14480                }
14481                if (!printedHeader) {
14482                    pw.println("  Recent tasks:");
14483                    printedHeader = true;
14484                    printedAnything = true;
14485                }
14486                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14487                        pw.println(tr);
14488                if (dumpAll) {
14489                    mRecentTasks.get(i).dump(pw, "    ");
14490                }
14491            }
14492        }
14493
14494        if (!printedAnything) {
14495            pw.println("  (nothing)");
14496        }
14497    }
14498
14499    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14500            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14501        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14502
14503        int dumpUid = 0;
14504        if (dumpPackage != null) {
14505            IPackageManager pm = AppGlobals.getPackageManager();
14506            try {
14507                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
14508            } catch (RemoteException e) {
14509            }
14510        }
14511
14512        boolean printedAnything = false;
14513
14514        final long now = SystemClock.uptimeMillis();
14515
14516        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14517            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14518                    = mAssociations.valueAt(i1);
14519            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14520                SparseArray<ArrayMap<String, Association>> sourceUids
14521                        = targetComponents.valueAt(i2);
14522                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14523                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14524                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14525                        Association ass = sourceProcesses.valueAt(i4);
14526                        if (dumpPackage != null) {
14527                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14528                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14529                                continue;
14530                            }
14531                        }
14532                        printedAnything = true;
14533                        pw.print("  ");
14534                        pw.print(ass.mTargetProcess);
14535                        pw.print("/");
14536                        UserHandle.formatUid(pw, ass.mTargetUid);
14537                        pw.print(" <- ");
14538                        pw.print(ass.mSourceProcess);
14539                        pw.print("/");
14540                        UserHandle.formatUid(pw, ass.mSourceUid);
14541                        pw.println();
14542                        pw.print("    via ");
14543                        pw.print(ass.mTargetComponent.flattenToShortString());
14544                        pw.println();
14545                        pw.print("    ");
14546                        long dur = ass.mTime;
14547                        if (ass.mNesting > 0) {
14548                            dur += now - ass.mStartTime;
14549                        }
14550                        TimeUtils.formatDuration(dur, pw);
14551                        pw.print(" (");
14552                        pw.print(ass.mCount);
14553                        pw.print(" times)");
14554                        pw.print("  ");
14555                        for (int i=0; i<ass.mStateTimes.length; i++) {
14556                            long amt = ass.mStateTimes[i];
14557                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14558                                amt += now - ass.mLastStateUptime;
14559                            }
14560                            if (amt != 0) {
14561                                pw.print(" ");
14562                                pw.print(ProcessList.makeProcStateString(
14563                                            i + ActivityManager.MIN_PROCESS_STATE));
14564                                pw.print("=");
14565                                TimeUtils.formatDuration(amt, pw);
14566                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14567                                    pw.print("*");
14568                                }
14569                            }
14570                        }
14571                        pw.println();
14572                        if (ass.mNesting > 0) {
14573                            pw.print("    Currently active: ");
14574                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14575                            pw.println();
14576                        }
14577                    }
14578                }
14579            }
14580
14581        }
14582
14583        if (!printedAnything) {
14584            pw.println("  (nothing)");
14585        }
14586    }
14587
14588    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14589            String header, boolean needSep) {
14590        boolean printed = false;
14591        int whichAppId = -1;
14592        if (dumpPackage != null) {
14593            try {
14594                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14595                        dumpPackage, 0);
14596                whichAppId = UserHandle.getAppId(info.uid);
14597            } catch (NameNotFoundException e) {
14598                e.printStackTrace();
14599            }
14600        }
14601        for (int i=0; i<uids.size(); i++) {
14602            UidRecord uidRec = uids.valueAt(i);
14603            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14604                continue;
14605            }
14606            if (!printed) {
14607                printed = true;
14608                if (needSep) {
14609                    pw.println();
14610                }
14611                pw.print("  ");
14612                pw.println(header);
14613                needSep = true;
14614            }
14615            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14616            pw.print(": "); pw.println(uidRec);
14617        }
14618        return printed;
14619    }
14620
14621    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14622            int opti, boolean dumpAll, String dumpPackage) {
14623        boolean needSep = false;
14624        boolean printedAnything = false;
14625        int numPers = 0;
14626
14627        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14628
14629        if (dumpAll) {
14630            final int NP = mProcessNames.getMap().size();
14631            for (int ip=0; ip<NP; ip++) {
14632                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14633                final int NA = procs.size();
14634                for (int ia=0; ia<NA; ia++) {
14635                    ProcessRecord r = procs.valueAt(ia);
14636                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14637                        continue;
14638                    }
14639                    if (!needSep) {
14640                        pw.println("  All known processes:");
14641                        needSep = true;
14642                        printedAnything = true;
14643                    }
14644                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14645                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14646                        pw.print(" "); pw.println(r);
14647                    r.dump(pw, "    ");
14648                    if (r.persistent) {
14649                        numPers++;
14650                    }
14651                }
14652            }
14653        }
14654
14655        if (mIsolatedProcesses.size() > 0) {
14656            boolean printed = false;
14657            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14658                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14659                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14660                    continue;
14661                }
14662                if (!printed) {
14663                    if (needSep) {
14664                        pw.println();
14665                    }
14666                    pw.println("  Isolated process list (sorted by uid):");
14667                    printedAnything = true;
14668                    printed = true;
14669                    needSep = true;
14670                }
14671                pw.println(String.format("%sIsolated #%2d: %s",
14672                        "    ", i, r.toString()));
14673            }
14674        }
14675
14676        if (mActiveUids.size() > 0) {
14677            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14678                printedAnything = needSep = true;
14679            }
14680        }
14681        if (mValidateUids.size() > 0) {
14682            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14683                printedAnything = needSep = true;
14684            }
14685        }
14686
14687        if (mLruProcesses.size() > 0) {
14688            if (needSep) {
14689                pw.println();
14690            }
14691            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14692                    pw.print(" total, non-act at ");
14693                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14694                    pw.print(", non-svc at ");
14695                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14696                    pw.println("):");
14697            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14698            needSep = true;
14699            printedAnything = true;
14700        }
14701
14702        if (dumpAll || dumpPackage != null) {
14703            synchronized (mPidsSelfLocked) {
14704                boolean printed = false;
14705                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14706                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14707                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14708                        continue;
14709                    }
14710                    if (!printed) {
14711                        if (needSep) pw.println();
14712                        needSep = true;
14713                        pw.println("  PID mappings:");
14714                        printed = true;
14715                        printedAnything = true;
14716                    }
14717                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14718                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14719                }
14720            }
14721        }
14722
14723        if (mForegroundProcesses.size() > 0) {
14724            synchronized (mPidsSelfLocked) {
14725                boolean printed = false;
14726                for (int i=0; i<mForegroundProcesses.size(); i++) {
14727                    ProcessRecord r = mPidsSelfLocked.get(
14728                            mForegroundProcesses.valueAt(i).pid);
14729                    if (dumpPackage != null && (r == null
14730                            || !r.pkgList.containsKey(dumpPackage))) {
14731                        continue;
14732                    }
14733                    if (!printed) {
14734                        if (needSep) pw.println();
14735                        needSep = true;
14736                        pw.println("  Foreground Processes:");
14737                        printed = true;
14738                        printedAnything = true;
14739                    }
14740                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14741                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14742                }
14743            }
14744        }
14745
14746        if (mPersistentStartingProcesses.size() > 0) {
14747            if (needSep) pw.println();
14748            needSep = true;
14749            printedAnything = true;
14750            pw.println("  Persisent processes that are starting:");
14751            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14752                    "Starting Norm", "Restarting PERS", dumpPackage);
14753        }
14754
14755        if (mRemovedProcesses.size() > 0) {
14756            if (needSep) pw.println();
14757            needSep = true;
14758            printedAnything = true;
14759            pw.println("  Processes that are being removed:");
14760            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14761                    "Removed Norm", "Removed PERS", dumpPackage);
14762        }
14763
14764        if (mProcessesOnHold.size() > 0) {
14765            if (needSep) pw.println();
14766            needSep = true;
14767            printedAnything = true;
14768            pw.println("  Processes that are on old until the system is ready:");
14769            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14770                    "OnHold Norm", "OnHold PERS", dumpPackage);
14771        }
14772
14773        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14774
14775        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14776        if (needSep) {
14777            printedAnything = true;
14778        }
14779
14780        if (dumpPackage == null) {
14781            pw.println();
14782            needSep = false;
14783            mUserController.dump(pw, dumpAll);
14784        }
14785        if (mHomeProcess != null && (dumpPackage == null
14786                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14787            if (needSep) {
14788                pw.println();
14789                needSep = false;
14790            }
14791            pw.println("  mHomeProcess: " + mHomeProcess);
14792        }
14793        if (mPreviousProcess != null && (dumpPackage == null
14794                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14795            if (needSep) {
14796                pw.println();
14797                needSep = false;
14798            }
14799            pw.println("  mPreviousProcess: " + mPreviousProcess);
14800        }
14801        if (dumpAll) {
14802            StringBuilder sb = new StringBuilder(128);
14803            sb.append("  mPreviousProcessVisibleTime: ");
14804            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14805            pw.println(sb);
14806        }
14807        if (mHeavyWeightProcess != null && (dumpPackage == null
14808                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14809            if (needSep) {
14810                pw.println();
14811                needSep = false;
14812            }
14813            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14814        }
14815        if (dumpPackage == null) {
14816            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14817            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14818        }
14819        if (dumpAll) {
14820            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14821            if (mCompatModePackages.getPackages().size() > 0) {
14822                boolean printed = false;
14823                for (Map.Entry<String, Integer> entry
14824                        : mCompatModePackages.getPackages().entrySet()) {
14825                    String pkg = entry.getKey();
14826                    int mode = entry.getValue();
14827                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14828                        continue;
14829                    }
14830                    if (!printed) {
14831                        pw.println("  mScreenCompatPackages:");
14832                        printed = true;
14833                    }
14834                    pw.print("    "); pw.print(pkg); pw.print(": ");
14835                            pw.print(mode); pw.println();
14836                }
14837            }
14838            final int NI = mUidObservers.getRegisteredCallbackCount();
14839            boolean printed = false;
14840            for (int i=0; i<NI; i++) {
14841                final UidObserverRegistration reg = (UidObserverRegistration)
14842                        mUidObservers.getRegisteredCallbackCookie(i);
14843                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
14844                    if (!printed) {
14845                        pw.println("  mUidObservers:");
14846                        printed = true;
14847                    }
14848                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
14849                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
14850                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
14851                        pw.print(" IDLE");
14852                    }
14853                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
14854                        pw.print(" ACT" );
14855                    }
14856                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
14857                        pw.print(" GONE");
14858                    }
14859                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
14860                        pw.print(" STATE");
14861                        pw.print(" (cut="); pw.print(reg.cutpoint);
14862                        pw.print(")");
14863                    }
14864                    pw.println();
14865                    if (reg.lastProcStates != null) {
14866                        final int NJ = reg.lastProcStates.size();
14867                        for (int j=0; j<NJ; j++) {
14868                            pw.print("      Last ");
14869                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
14870                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
14871                        }
14872                    }
14873                }
14874            }
14875        }
14876        if (dumpPackage == null) {
14877            pw.println("  mWakefulness="
14878                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14879            pw.println("  mSleepTokens=" + mSleepTokens);
14880            pw.println("  mSleeping=" + mSleeping);
14881            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14882            if (mRunningVoice != null) {
14883                pw.println("  mRunningVoice=" + mRunningVoice);
14884                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14885            }
14886        }
14887        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14888                || mOrigWaitForDebugger) {
14889            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14890                    || dumpPackage.equals(mOrigDebugApp)) {
14891                if (needSep) {
14892                    pw.println();
14893                    needSep = false;
14894                }
14895                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14896                        + " mDebugTransient=" + mDebugTransient
14897                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14898            }
14899        }
14900        if (mCurAppTimeTracker != null) {
14901            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14902        }
14903        if (mMemWatchProcesses.getMap().size() > 0) {
14904            pw.println("  Mem watch processes:");
14905            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14906                    = mMemWatchProcesses.getMap();
14907            for (int i=0; i<procs.size(); i++) {
14908                final String proc = procs.keyAt(i);
14909                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14910                for (int j=0; j<uids.size(); j++) {
14911                    if (needSep) {
14912                        pw.println();
14913                        needSep = false;
14914                    }
14915                    StringBuilder sb = new StringBuilder();
14916                    sb.append("    ").append(proc).append('/');
14917                    UserHandle.formatUid(sb, uids.keyAt(j));
14918                    Pair<Long, String> val = uids.valueAt(j);
14919                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14920                    if (val.second != null) {
14921                        sb.append(", report to ").append(val.second);
14922                    }
14923                    pw.println(sb.toString());
14924                }
14925            }
14926            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14927            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14928            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14929                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14930        }
14931        if (mTrackAllocationApp != null) {
14932            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14933                if (needSep) {
14934                    pw.println();
14935                    needSep = false;
14936                }
14937                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14938            }
14939        }
14940        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14941                || mProfileFd != null) {
14942            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14943                if (needSep) {
14944                    pw.println();
14945                    needSep = false;
14946                }
14947                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14948                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14949                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14950                        + mAutoStopProfiler);
14951                pw.println("  mProfileType=" + mProfileType);
14952            }
14953        }
14954        if (mNativeDebuggingApp != null) {
14955            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14956                if (needSep) {
14957                    pw.println();
14958                    needSep = false;
14959                }
14960                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14961            }
14962        }
14963        if (dumpPackage == null) {
14964            if (mAlwaysFinishActivities) {
14965                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
14966            }
14967            if (mController != null) {
14968                pw.println("  mController=" + mController
14969                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14970            }
14971            if (dumpAll) {
14972                pw.println("  Total persistent processes: " + numPers);
14973                pw.println("  mProcessesReady=" + mProcessesReady
14974                        + " mSystemReady=" + mSystemReady
14975                        + " mBooted=" + mBooted
14976                        + " mFactoryTest=" + mFactoryTest);
14977                pw.println("  mBooting=" + mBooting
14978                        + " mCallFinishBooting=" + mCallFinishBooting
14979                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14980                pw.print("  mLastPowerCheckRealtime=");
14981                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14982                        pw.println("");
14983                pw.print("  mLastPowerCheckUptime=");
14984                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14985                        pw.println("");
14986                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14987                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14988                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14989                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14990                        + " (" + mLruProcesses.size() + " total)"
14991                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14992                        + " mNumServiceProcs=" + mNumServiceProcs
14993                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14994                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14995                        + " mLastMemoryLevel=" + mLastMemoryLevel
14996                        + " mLastNumProcesses=" + mLastNumProcesses);
14997                long now = SystemClock.uptimeMillis();
14998                pw.print("  mLastIdleTime=");
14999                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15000                        pw.print(" mLowRamSinceLastIdle=");
15001                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15002                        pw.println();
15003            }
15004        }
15005
15006        if (!printedAnything) {
15007            pw.println("  (nothing)");
15008        }
15009    }
15010
15011    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15012            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15013        if (mProcessesToGc.size() > 0) {
15014            boolean printed = false;
15015            long now = SystemClock.uptimeMillis();
15016            for (int i=0; i<mProcessesToGc.size(); i++) {
15017                ProcessRecord proc = mProcessesToGc.get(i);
15018                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15019                    continue;
15020                }
15021                if (!printed) {
15022                    if (needSep) pw.println();
15023                    needSep = true;
15024                    pw.println("  Processes that are waiting to GC:");
15025                    printed = true;
15026                }
15027                pw.print("    Process "); pw.println(proc);
15028                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15029                        pw.print(", last gced=");
15030                        pw.print(now-proc.lastRequestedGc);
15031                        pw.print(" ms ago, last lowMem=");
15032                        pw.print(now-proc.lastLowMemory);
15033                        pw.println(" ms ago");
15034
15035            }
15036        }
15037        return needSep;
15038    }
15039
15040    void printOomLevel(PrintWriter pw, String name, int adj) {
15041        pw.print("    ");
15042        if (adj >= 0) {
15043            pw.print(' ');
15044            if (adj < 10) pw.print(' ');
15045        } else {
15046            if (adj > -10) pw.print(' ');
15047        }
15048        pw.print(adj);
15049        pw.print(": ");
15050        pw.print(name);
15051        pw.print(" (");
15052        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15053        pw.println(")");
15054    }
15055
15056    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15057            int opti, boolean dumpAll) {
15058        boolean needSep = false;
15059
15060        if (mLruProcesses.size() > 0) {
15061            if (needSep) pw.println();
15062            needSep = true;
15063            pw.println("  OOM levels:");
15064            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15065            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15066            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15067            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15068            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15069            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15070            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15071            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15072            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15073            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15074            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15075            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15076            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15077            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15078
15079            if (needSep) pw.println();
15080            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15081                    pw.print(" total, non-act at ");
15082                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15083                    pw.print(", non-svc at ");
15084                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15085                    pw.println("):");
15086            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15087            needSep = true;
15088        }
15089
15090        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15091
15092        pw.println();
15093        pw.println("  mHomeProcess: " + mHomeProcess);
15094        pw.println("  mPreviousProcess: " + mPreviousProcess);
15095        if (mHeavyWeightProcess != null) {
15096            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15097        }
15098
15099        return true;
15100    }
15101
15102    /**
15103     * There are three ways to call this:
15104     *  - no provider specified: dump all the providers
15105     *  - a flattened component name that matched an existing provider was specified as the
15106     *    first arg: dump that one provider
15107     *  - the first arg isn't the flattened component name of an existing provider:
15108     *    dump all providers whose component contains the first arg as a substring
15109     */
15110    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15111            int opti, boolean dumpAll) {
15112        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15113    }
15114
15115    static class ItemMatcher {
15116        ArrayList<ComponentName> components;
15117        ArrayList<String> strings;
15118        ArrayList<Integer> objects;
15119        boolean all;
15120
15121        ItemMatcher() {
15122            all = true;
15123        }
15124
15125        void build(String name) {
15126            ComponentName componentName = ComponentName.unflattenFromString(name);
15127            if (componentName != null) {
15128                if (components == null) {
15129                    components = new ArrayList<ComponentName>();
15130                }
15131                components.add(componentName);
15132                all = false;
15133            } else {
15134                int objectId = 0;
15135                // Not a '/' separated full component name; maybe an object ID?
15136                try {
15137                    objectId = Integer.parseInt(name, 16);
15138                    if (objects == null) {
15139                        objects = new ArrayList<Integer>();
15140                    }
15141                    objects.add(objectId);
15142                    all = false;
15143                } catch (RuntimeException e) {
15144                    // Not an integer; just do string match.
15145                    if (strings == null) {
15146                        strings = new ArrayList<String>();
15147                    }
15148                    strings.add(name);
15149                    all = false;
15150                }
15151            }
15152        }
15153
15154        int build(String[] args, int opti) {
15155            for (; opti<args.length; opti++) {
15156                String name = args[opti];
15157                if ("--".equals(name)) {
15158                    return opti+1;
15159                }
15160                build(name);
15161            }
15162            return opti;
15163        }
15164
15165        boolean match(Object object, ComponentName comp) {
15166            if (all) {
15167                return true;
15168            }
15169            if (components != null) {
15170                for (int i=0; i<components.size(); i++) {
15171                    if (components.get(i).equals(comp)) {
15172                        return true;
15173                    }
15174                }
15175            }
15176            if (objects != null) {
15177                for (int i=0; i<objects.size(); i++) {
15178                    if (System.identityHashCode(object) == objects.get(i)) {
15179                        return true;
15180                    }
15181                }
15182            }
15183            if (strings != null) {
15184                String flat = comp.flattenToString();
15185                for (int i=0; i<strings.size(); i++) {
15186                    if (flat.contains(strings.get(i))) {
15187                        return true;
15188                    }
15189                }
15190            }
15191            return false;
15192        }
15193    }
15194
15195    /**
15196     * There are three things that cmd can be:
15197     *  - a flattened component name that matches an existing activity
15198     *  - the cmd arg isn't the flattened component name of an existing activity:
15199     *    dump all activity whose component contains the cmd as a substring
15200     *  - A hex number of the ActivityRecord object instance.
15201     */
15202    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15203            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15204        ArrayList<ActivityRecord> activities;
15205
15206        synchronized (this) {
15207            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15208        }
15209
15210        if (activities.size() <= 0) {
15211            return false;
15212        }
15213
15214        String[] newArgs = new String[args.length - opti];
15215        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15216
15217        TaskRecord lastTask = null;
15218        boolean needSep = false;
15219        for (int i=activities.size()-1; i>=0; i--) {
15220            ActivityRecord r = activities.get(i);
15221            if (needSep) {
15222                pw.println();
15223            }
15224            needSep = true;
15225            synchronized (this) {
15226                if (lastTask != r.task) {
15227                    lastTask = r.task;
15228                    pw.print("TASK "); pw.print(lastTask.affinity);
15229                            pw.print(" id="); pw.print(lastTask.taskId);
15230                            pw.print(" userId="); pw.println(lastTask.userId);
15231                    if (dumpAll) {
15232                        lastTask.dump(pw, "  ");
15233                    }
15234                }
15235            }
15236            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15237        }
15238        return true;
15239    }
15240
15241    /**
15242     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15243     * there is a thread associated with the activity.
15244     */
15245    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15246            final ActivityRecord r, String[] args, boolean dumpAll) {
15247        String innerPrefix = prefix + "  ";
15248        synchronized (this) {
15249            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15250                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15251                    pw.print(" pid=");
15252                    if (r.app != null) pw.println(r.app.pid);
15253                    else pw.println("(not running)");
15254            if (dumpAll) {
15255                r.dump(pw, innerPrefix);
15256            }
15257        }
15258        if (r.app != null && r.app.thread != null) {
15259            // flush anything that is already in the PrintWriter since the thread is going
15260            // to write to the file descriptor directly
15261            pw.flush();
15262            try {
15263                TransferPipe tp = new TransferPipe();
15264                try {
15265                    r.app.thread.dumpActivity(tp.getWriteFd(),
15266                            r.appToken, innerPrefix, args);
15267                    tp.go(fd);
15268                } finally {
15269                    tp.kill();
15270                }
15271            } catch (IOException e) {
15272                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15273            } catch (RemoteException e) {
15274                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15275            }
15276        }
15277    }
15278
15279    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15280            int opti, boolean dumpAll, String dumpPackage) {
15281        boolean needSep = false;
15282        boolean onlyHistory = false;
15283        boolean printedAnything = false;
15284
15285        if ("history".equals(dumpPackage)) {
15286            if (opti < args.length && "-s".equals(args[opti])) {
15287                dumpAll = false;
15288            }
15289            onlyHistory = true;
15290            dumpPackage = null;
15291        }
15292
15293        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15294        if (!onlyHistory && dumpAll) {
15295            if (mRegisteredReceivers.size() > 0) {
15296                boolean printed = false;
15297                Iterator it = mRegisteredReceivers.values().iterator();
15298                while (it.hasNext()) {
15299                    ReceiverList r = (ReceiverList)it.next();
15300                    if (dumpPackage != null && (r.app == null ||
15301                            !dumpPackage.equals(r.app.info.packageName))) {
15302                        continue;
15303                    }
15304                    if (!printed) {
15305                        pw.println("  Registered Receivers:");
15306                        needSep = true;
15307                        printed = true;
15308                        printedAnything = true;
15309                    }
15310                    pw.print("  * "); pw.println(r);
15311                    r.dump(pw, "    ");
15312                }
15313            }
15314
15315            if (mReceiverResolver.dump(pw, needSep ?
15316                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15317                    "    ", dumpPackage, false, false)) {
15318                needSep = true;
15319                printedAnything = true;
15320            }
15321        }
15322
15323        for (BroadcastQueue q : mBroadcastQueues) {
15324            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15325            printedAnything |= needSep;
15326        }
15327
15328        needSep = true;
15329
15330        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15331            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15332                if (needSep) {
15333                    pw.println();
15334                }
15335                needSep = true;
15336                printedAnything = true;
15337                pw.print("  Sticky broadcasts for user ");
15338                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15339                StringBuilder sb = new StringBuilder(128);
15340                for (Map.Entry<String, ArrayList<Intent>> ent
15341                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15342                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15343                    if (dumpAll) {
15344                        pw.println(":");
15345                        ArrayList<Intent> intents = ent.getValue();
15346                        final int N = intents.size();
15347                        for (int i=0; i<N; i++) {
15348                            sb.setLength(0);
15349                            sb.append("    Intent: ");
15350                            intents.get(i).toShortString(sb, false, true, false, false);
15351                            pw.println(sb.toString());
15352                            Bundle bundle = intents.get(i).getExtras();
15353                            if (bundle != null) {
15354                                pw.print("      ");
15355                                pw.println(bundle.toString());
15356                            }
15357                        }
15358                    } else {
15359                        pw.println("");
15360                    }
15361                }
15362            }
15363        }
15364
15365        if (!onlyHistory && dumpAll) {
15366            pw.println();
15367            for (BroadcastQueue queue : mBroadcastQueues) {
15368                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15369                        + queue.mBroadcastsScheduled);
15370            }
15371            pw.println("  mHandler:");
15372            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15373            needSep = true;
15374            printedAnything = true;
15375        }
15376
15377        if (!printedAnything) {
15378            pw.println("  (nothing)");
15379        }
15380    }
15381
15382    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15383            int opti, boolean dumpAll, String dumpPackage) {
15384        if (mCurBroadcastStats == null) {
15385            return;
15386        }
15387
15388        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15389        final long now = SystemClock.elapsedRealtime();
15390        if (mLastBroadcastStats != null) {
15391            pw.print("  Last stats (from ");
15392            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15393            pw.print(" to ");
15394            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15395            pw.print(", ");
15396            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15397                    - mLastBroadcastStats.mStartUptime, pw);
15398            pw.println(" uptime):");
15399            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15400                pw.println("    (nothing)");
15401            }
15402            pw.println();
15403        }
15404        pw.print("  Current stats (from ");
15405        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15406        pw.print(" to now, ");
15407        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15408                - mCurBroadcastStats.mStartUptime, pw);
15409        pw.println(" uptime):");
15410        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15411            pw.println("    (nothing)");
15412        }
15413    }
15414
15415    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15416            int opti, boolean fullCheckin, String dumpPackage) {
15417        if (mCurBroadcastStats == null) {
15418            return;
15419        }
15420
15421        if (mLastBroadcastStats != null) {
15422            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15423            if (fullCheckin) {
15424                mLastBroadcastStats = null;
15425                return;
15426            }
15427        }
15428        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15429        if (fullCheckin) {
15430            mCurBroadcastStats = null;
15431        }
15432    }
15433
15434    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15435            int opti, boolean dumpAll, String dumpPackage) {
15436        boolean needSep;
15437        boolean printedAnything = false;
15438
15439        ItemMatcher matcher = new ItemMatcher();
15440        matcher.build(args, opti);
15441
15442        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15443
15444        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15445        printedAnything |= needSep;
15446
15447        if (mLaunchingProviders.size() > 0) {
15448            boolean printed = false;
15449            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15450                ContentProviderRecord r = mLaunchingProviders.get(i);
15451                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15452                    continue;
15453                }
15454                if (!printed) {
15455                    if (needSep) pw.println();
15456                    needSep = true;
15457                    pw.println("  Launching content providers:");
15458                    printed = true;
15459                    printedAnything = true;
15460                }
15461                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15462                        pw.println(r);
15463            }
15464        }
15465
15466        if (!printedAnything) {
15467            pw.println("  (nothing)");
15468        }
15469    }
15470
15471    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15472            int opti, boolean dumpAll, String dumpPackage) {
15473        boolean needSep = false;
15474        boolean printedAnything = false;
15475
15476        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15477
15478        if (mGrantedUriPermissions.size() > 0) {
15479            boolean printed = false;
15480            int dumpUid = -2;
15481            if (dumpPackage != null) {
15482                try {
15483                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15484                            MATCH_ANY_USER, 0);
15485                } catch (NameNotFoundException e) {
15486                    dumpUid = -1;
15487                }
15488            }
15489            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15490                int uid = mGrantedUriPermissions.keyAt(i);
15491                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15492                    continue;
15493                }
15494                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15495                if (!printed) {
15496                    if (needSep) pw.println();
15497                    needSep = true;
15498                    pw.println("  Granted Uri Permissions:");
15499                    printed = true;
15500                    printedAnything = true;
15501                }
15502                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15503                for (UriPermission perm : perms.values()) {
15504                    pw.print("    "); pw.println(perm);
15505                    if (dumpAll) {
15506                        perm.dump(pw, "      ");
15507                    }
15508                }
15509            }
15510        }
15511
15512        if (!printedAnything) {
15513            pw.println("  (nothing)");
15514        }
15515    }
15516
15517    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15518            int opti, boolean dumpAll, String dumpPackage) {
15519        boolean printed = false;
15520
15521        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15522
15523        if (mIntentSenderRecords.size() > 0) {
15524            Iterator<WeakReference<PendingIntentRecord>> it
15525                    = mIntentSenderRecords.values().iterator();
15526            while (it.hasNext()) {
15527                WeakReference<PendingIntentRecord> ref = it.next();
15528                PendingIntentRecord rec = ref != null ? ref.get(): null;
15529                if (dumpPackage != null && (rec == null
15530                        || !dumpPackage.equals(rec.key.packageName))) {
15531                    continue;
15532                }
15533                printed = true;
15534                if (rec != null) {
15535                    pw.print("  * "); pw.println(rec);
15536                    if (dumpAll) {
15537                        rec.dump(pw, "    ");
15538                    }
15539                } else {
15540                    pw.print("  * "); pw.println(ref);
15541                }
15542            }
15543        }
15544
15545        if (!printed) {
15546            pw.println("  (nothing)");
15547        }
15548    }
15549
15550    private static final int dumpProcessList(PrintWriter pw,
15551            ActivityManagerService service, List list,
15552            String prefix, String normalLabel, String persistentLabel,
15553            String dumpPackage) {
15554        int numPers = 0;
15555        final int N = list.size()-1;
15556        for (int i=N; i>=0; i--) {
15557            ProcessRecord r = (ProcessRecord)list.get(i);
15558            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15559                continue;
15560            }
15561            pw.println(String.format("%s%s #%2d: %s",
15562                    prefix, (r.persistent ? persistentLabel : normalLabel),
15563                    i, r.toString()));
15564            if (r.persistent) {
15565                numPers++;
15566            }
15567        }
15568        return numPers;
15569    }
15570
15571    private static final boolean dumpProcessOomList(PrintWriter pw,
15572            ActivityManagerService service, List<ProcessRecord> origList,
15573            String prefix, String normalLabel, String persistentLabel,
15574            boolean inclDetails, String dumpPackage) {
15575
15576        ArrayList<Pair<ProcessRecord, Integer>> list
15577                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15578        for (int i=0; i<origList.size(); i++) {
15579            ProcessRecord r = origList.get(i);
15580            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15581                continue;
15582            }
15583            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15584        }
15585
15586        if (list.size() <= 0) {
15587            return false;
15588        }
15589
15590        Comparator<Pair<ProcessRecord, Integer>> comparator
15591                = new Comparator<Pair<ProcessRecord, Integer>>() {
15592            @Override
15593            public int compare(Pair<ProcessRecord, Integer> object1,
15594                    Pair<ProcessRecord, Integer> object2) {
15595                if (object1.first.setAdj != object2.first.setAdj) {
15596                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15597                }
15598                if (object1.first.setProcState != object2.first.setProcState) {
15599                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15600                }
15601                if (object1.second.intValue() != object2.second.intValue()) {
15602                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15603                }
15604                return 0;
15605            }
15606        };
15607
15608        Collections.sort(list, comparator);
15609
15610        final long curRealtime = SystemClock.elapsedRealtime();
15611        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15612        final long curUptime = SystemClock.uptimeMillis();
15613        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15614
15615        for (int i=list.size()-1; i>=0; i--) {
15616            ProcessRecord r = list.get(i).first;
15617            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15618            char schedGroup;
15619            switch (r.setSchedGroup) {
15620                case ProcessList.SCHED_GROUP_BACKGROUND:
15621                    schedGroup = 'B';
15622                    break;
15623                case ProcessList.SCHED_GROUP_DEFAULT:
15624                    schedGroup = 'F';
15625                    break;
15626                case ProcessList.SCHED_GROUP_TOP_APP:
15627                    schedGroup = 'T';
15628                    break;
15629                default:
15630                    schedGroup = '?';
15631                    break;
15632            }
15633            char foreground;
15634            if (r.foregroundActivities) {
15635                foreground = 'A';
15636            } else if (r.foregroundServices) {
15637                foreground = 'S';
15638            } else {
15639                foreground = ' ';
15640            }
15641            String procState = ProcessList.makeProcStateString(r.curProcState);
15642            pw.print(prefix);
15643            pw.print(r.persistent ? persistentLabel : normalLabel);
15644            pw.print(" #");
15645            int num = (origList.size()-1)-list.get(i).second;
15646            if (num < 10) pw.print(' ');
15647            pw.print(num);
15648            pw.print(": ");
15649            pw.print(oomAdj);
15650            pw.print(' ');
15651            pw.print(schedGroup);
15652            pw.print('/');
15653            pw.print(foreground);
15654            pw.print('/');
15655            pw.print(procState);
15656            pw.print(" trm:");
15657            if (r.trimMemoryLevel < 10) pw.print(' ');
15658            pw.print(r.trimMemoryLevel);
15659            pw.print(' ');
15660            pw.print(r.toShortString());
15661            pw.print(" (");
15662            pw.print(r.adjType);
15663            pw.println(')');
15664            if (r.adjSource != null || r.adjTarget != null) {
15665                pw.print(prefix);
15666                pw.print("    ");
15667                if (r.adjTarget instanceof ComponentName) {
15668                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15669                } else if (r.adjTarget != null) {
15670                    pw.print(r.adjTarget.toString());
15671                } else {
15672                    pw.print("{null}");
15673                }
15674                pw.print("<=");
15675                if (r.adjSource instanceof ProcessRecord) {
15676                    pw.print("Proc{");
15677                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15678                    pw.println("}");
15679                } else if (r.adjSource != null) {
15680                    pw.println(r.adjSource.toString());
15681                } else {
15682                    pw.println("{null}");
15683                }
15684            }
15685            if (inclDetails) {
15686                pw.print(prefix);
15687                pw.print("    ");
15688                pw.print("oom: max="); pw.print(r.maxAdj);
15689                pw.print(" curRaw="); pw.print(r.curRawAdj);
15690                pw.print(" setRaw="); pw.print(r.setRawAdj);
15691                pw.print(" cur="); pw.print(r.curAdj);
15692                pw.print(" set="); pw.println(r.setAdj);
15693                pw.print(prefix);
15694                pw.print("    ");
15695                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15696                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15697                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15698                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15699                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15700                pw.println();
15701                pw.print(prefix);
15702                pw.print("    ");
15703                pw.print("cached="); pw.print(r.cached);
15704                pw.print(" empty="); pw.print(r.empty);
15705                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15706
15707                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15708                    if (r.lastWakeTime != 0) {
15709                        long wtime;
15710                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15711                        synchronized (stats) {
15712                            wtime = stats.getProcessWakeTime(r.info.uid,
15713                                    r.pid, curRealtime);
15714                        }
15715                        long timeUsed = wtime - r.lastWakeTime;
15716                        pw.print(prefix);
15717                        pw.print("    ");
15718                        pw.print("keep awake over ");
15719                        TimeUtils.formatDuration(realtimeSince, pw);
15720                        pw.print(" used ");
15721                        TimeUtils.formatDuration(timeUsed, pw);
15722                        pw.print(" (");
15723                        pw.print((timeUsed*100)/realtimeSince);
15724                        pw.println("%)");
15725                    }
15726                    if (r.lastCpuTime != 0) {
15727                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15728                        pw.print(prefix);
15729                        pw.print("    ");
15730                        pw.print("run cpu over ");
15731                        TimeUtils.formatDuration(uptimeSince, pw);
15732                        pw.print(" used ");
15733                        TimeUtils.formatDuration(timeUsed, pw);
15734                        pw.print(" (");
15735                        pw.print((timeUsed*100)/uptimeSince);
15736                        pw.println("%)");
15737                    }
15738                }
15739            }
15740        }
15741        return true;
15742    }
15743
15744    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15745            String[] args) {
15746        ArrayList<ProcessRecord> procs;
15747        synchronized (this) {
15748            if (args != null && args.length > start
15749                    && args[start].charAt(0) != '-') {
15750                procs = new ArrayList<ProcessRecord>();
15751                int pid = -1;
15752                try {
15753                    pid = Integer.parseInt(args[start]);
15754                } catch (NumberFormatException e) {
15755                }
15756                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15757                    ProcessRecord proc = mLruProcesses.get(i);
15758                    if (proc.pid == pid) {
15759                        procs.add(proc);
15760                    } else if (allPkgs && proc.pkgList != null
15761                            && proc.pkgList.containsKey(args[start])) {
15762                        procs.add(proc);
15763                    } else if (proc.processName.equals(args[start])) {
15764                        procs.add(proc);
15765                    }
15766                }
15767                if (procs.size() <= 0) {
15768                    return null;
15769                }
15770            } else {
15771                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15772            }
15773        }
15774        return procs;
15775    }
15776
15777    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15778            PrintWriter pw, String[] args) {
15779        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15780        if (procs == null) {
15781            pw.println("No process found for: " + args[0]);
15782            return;
15783        }
15784
15785        long uptime = SystemClock.uptimeMillis();
15786        long realtime = SystemClock.elapsedRealtime();
15787        pw.println("Applications Graphics Acceleration Info:");
15788        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15789
15790        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15791            ProcessRecord r = procs.get(i);
15792            if (r.thread != null) {
15793                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15794                pw.flush();
15795                try {
15796                    TransferPipe tp = new TransferPipe();
15797                    try {
15798                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15799                        tp.go(fd);
15800                    } finally {
15801                        tp.kill();
15802                    }
15803                } catch (IOException e) {
15804                    pw.println("Failure while dumping the app: " + r);
15805                    pw.flush();
15806                } catch (RemoteException e) {
15807                    pw.println("Got a RemoteException while dumping the app " + r);
15808                    pw.flush();
15809                }
15810            }
15811        }
15812    }
15813
15814    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15815        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15816        if (procs == null) {
15817            pw.println("No process found for: " + args[0]);
15818            return;
15819        }
15820
15821        pw.println("Applications Database Info:");
15822
15823        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15824            ProcessRecord r = procs.get(i);
15825            if (r.thread != null) {
15826                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15827                pw.flush();
15828                try {
15829                    TransferPipe tp = new TransferPipe();
15830                    try {
15831                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15832                        tp.go(fd);
15833                    } finally {
15834                        tp.kill();
15835                    }
15836                } catch (IOException e) {
15837                    pw.println("Failure while dumping the app: " + r);
15838                    pw.flush();
15839                } catch (RemoteException e) {
15840                    pw.println("Got a RemoteException while dumping the app " + r);
15841                    pw.flush();
15842                }
15843            }
15844        }
15845    }
15846
15847    final static class MemItem {
15848        final boolean isProc;
15849        final String label;
15850        final String shortLabel;
15851        final long pss;
15852        final long swapPss;
15853        final int id;
15854        final boolean hasActivities;
15855        ArrayList<MemItem> subitems;
15856
15857        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15858                boolean _hasActivities) {
15859            isProc = true;
15860            label = _label;
15861            shortLabel = _shortLabel;
15862            pss = _pss;
15863            swapPss = _swapPss;
15864            id = _id;
15865            hasActivities = _hasActivities;
15866        }
15867
15868        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15869            isProc = false;
15870            label = _label;
15871            shortLabel = _shortLabel;
15872            pss = _pss;
15873            swapPss = _swapPss;
15874            id = _id;
15875            hasActivities = false;
15876        }
15877    }
15878
15879    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15880            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15881        if (sort && !isCompact) {
15882            Collections.sort(items, new Comparator<MemItem>() {
15883                @Override
15884                public int compare(MemItem lhs, MemItem rhs) {
15885                    if (lhs.pss < rhs.pss) {
15886                        return 1;
15887                    } else if (lhs.pss > rhs.pss) {
15888                        return -1;
15889                    }
15890                    return 0;
15891                }
15892            });
15893        }
15894
15895        for (int i=0; i<items.size(); i++) {
15896            MemItem mi = items.get(i);
15897            if (!isCompact) {
15898                if (dumpSwapPss) {
15899                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15900                            mi.label, stringifyKBSize(mi.swapPss));
15901                } else {
15902                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15903                }
15904            } else if (mi.isProc) {
15905                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15906                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15907                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15908                pw.println(mi.hasActivities ? ",a" : ",e");
15909            } else {
15910                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15911                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15912            }
15913            if (mi.subitems != null) {
15914                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15915                        true, isCompact, dumpSwapPss);
15916            }
15917        }
15918    }
15919
15920    // These are in KB.
15921    static final long[] DUMP_MEM_BUCKETS = new long[] {
15922        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15923        120*1024, 160*1024, 200*1024,
15924        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15925        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15926    };
15927
15928    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15929            boolean stackLike) {
15930        int start = label.lastIndexOf('.');
15931        if (start >= 0) start++;
15932        else start = 0;
15933        int end = label.length();
15934        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15935            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15936                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15937                out.append(bucket);
15938                out.append(stackLike ? "MB." : "MB ");
15939                out.append(label, start, end);
15940                return;
15941            }
15942        }
15943        out.append(memKB/1024);
15944        out.append(stackLike ? "MB." : "MB ");
15945        out.append(label, start, end);
15946    }
15947
15948    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15949            ProcessList.NATIVE_ADJ,
15950            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15951            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15952            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15953            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15954            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15955            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15956    };
15957    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15958            "Native",
15959            "System", "Persistent", "Persistent Service", "Foreground",
15960            "Visible", "Perceptible",
15961            "Heavy Weight", "Backup",
15962            "A Services", "Home",
15963            "Previous", "B Services", "Cached"
15964    };
15965    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15966            "native",
15967            "sys", "pers", "persvc", "fore",
15968            "vis", "percept",
15969            "heavy", "backup",
15970            "servicea", "home",
15971            "prev", "serviceb", "cached"
15972    };
15973
15974    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15975            long realtime, boolean isCheckinRequest, boolean isCompact) {
15976        if (isCompact) {
15977            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15978        }
15979        if (isCheckinRequest || isCompact) {
15980            // short checkin version
15981            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15982        } else {
15983            pw.println("Applications Memory Usage (in Kilobytes):");
15984            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15985        }
15986    }
15987
15988    private static final int KSM_SHARED = 0;
15989    private static final int KSM_SHARING = 1;
15990    private static final int KSM_UNSHARED = 2;
15991    private static final int KSM_VOLATILE = 3;
15992
15993    private final long[] getKsmInfo() {
15994        long[] longOut = new long[4];
15995        final int[] SINGLE_LONG_FORMAT = new int[] {
15996            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15997        };
15998        long[] longTmp = new long[1];
15999        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16000                SINGLE_LONG_FORMAT, null, longTmp, null);
16001        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16002        longTmp[0] = 0;
16003        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16004                SINGLE_LONG_FORMAT, null, longTmp, null);
16005        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16006        longTmp[0] = 0;
16007        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16008                SINGLE_LONG_FORMAT, null, longTmp, null);
16009        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16010        longTmp[0] = 0;
16011        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16012                SINGLE_LONG_FORMAT, null, longTmp, null);
16013        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16014        return longOut;
16015    }
16016
16017    private static String stringifySize(long size, int order) {
16018        Locale locale = Locale.US;
16019        switch (order) {
16020            case 1:
16021                return String.format(locale, "%,13d", size);
16022            case 1024:
16023                return String.format(locale, "%,9dK", size / 1024);
16024            case 1024 * 1024:
16025                return String.format(locale, "%,5dM", size / 1024 / 1024);
16026            case 1024 * 1024 * 1024:
16027                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16028            default:
16029                throw new IllegalArgumentException("Invalid size order");
16030        }
16031    }
16032
16033    private static String stringifyKBSize(long size) {
16034        return stringifySize(size * 1024, 1024);
16035    }
16036
16037    // Update this version number in case you change the 'compact' format
16038    private static final int MEMINFO_COMPACT_VERSION = 1;
16039
16040    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16041            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16042        boolean dumpDetails = false;
16043        boolean dumpFullDetails = false;
16044        boolean dumpDalvik = false;
16045        boolean dumpSummaryOnly = false;
16046        boolean dumpUnreachable = false;
16047        boolean oomOnly = false;
16048        boolean isCompact = false;
16049        boolean localOnly = false;
16050        boolean packages = false;
16051        boolean isCheckinRequest = false;
16052        boolean dumpSwapPss = false;
16053
16054        int opti = 0;
16055        while (opti < args.length) {
16056            String opt = args[opti];
16057            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16058                break;
16059            }
16060            opti++;
16061            if ("-a".equals(opt)) {
16062                dumpDetails = true;
16063                dumpFullDetails = true;
16064                dumpDalvik = true;
16065                dumpSwapPss = true;
16066            } else if ("-d".equals(opt)) {
16067                dumpDalvik = true;
16068            } else if ("-c".equals(opt)) {
16069                isCompact = true;
16070            } else if ("-s".equals(opt)) {
16071                dumpDetails = true;
16072                dumpSummaryOnly = true;
16073            } else if ("-S".equals(opt)) {
16074                dumpSwapPss = true;
16075            } else if ("--unreachable".equals(opt)) {
16076                dumpUnreachable = true;
16077            } else if ("--oom".equals(opt)) {
16078                oomOnly = true;
16079            } else if ("--local".equals(opt)) {
16080                localOnly = true;
16081            } else if ("--package".equals(opt)) {
16082                packages = true;
16083            } else if ("--checkin".equals(opt)) {
16084                isCheckinRequest = true;
16085
16086            } else if ("-h".equals(opt)) {
16087                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16088                pw.println("  -a: include all available information for each process.");
16089                pw.println("  -d: include dalvik details.");
16090                pw.println("  -c: dump in a compact machine-parseable representation.");
16091                pw.println("  -s: dump only summary of application memory usage.");
16092                pw.println("  -S: dump also SwapPss.");
16093                pw.println("  --oom: only show processes organized by oom adj.");
16094                pw.println("  --local: only collect details locally, don't call process.");
16095                pw.println("  --package: interpret process arg as package, dumping all");
16096                pw.println("             processes that have loaded that package.");
16097                pw.println("  --checkin: dump data for a checkin");
16098                pw.println("If [process] is specified it can be the name or ");
16099                pw.println("pid of a specific process to dump.");
16100                return;
16101            } else {
16102                pw.println("Unknown argument: " + opt + "; use -h for help");
16103            }
16104        }
16105
16106        long uptime = SystemClock.uptimeMillis();
16107        long realtime = SystemClock.elapsedRealtime();
16108        final long[] tmpLong = new long[1];
16109
16110        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16111        if (procs == null) {
16112            // No Java processes.  Maybe they want to print a native process.
16113            if (args != null && args.length > opti
16114                    && args[opti].charAt(0) != '-') {
16115                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16116                        = new ArrayList<ProcessCpuTracker.Stats>();
16117                updateCpuStatsNow();
16118                int findPid = -1;
16119                try {
16120                    findPid = Integer.parseInt(args[opti]);
16121                } catch (NumberFormatException e) {
16122                }
16123                synchronized (mProcessCpuTracker) {
16124                    final int N = mProcessCpuTracker.countStats();
16125                    for (int i=0; i<N; i++) {
16126                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16127                        if (st.pid == findPid || (st.baseName != null
16128                                && st.baseName.equals(args[opti]))) {
16129                            nativeProcs.add(st);
16130                        }
16131                    }
16132                }
16133                if (nativeProcs.size() > 0) {
16134                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16135                            isCompact);
16136                    Debug.MemoryInfo mi = null;
16137                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16138                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16139                        final int pid = r.pid;
16140                        if (!isCheckinRequest && dumpDetails) {
16141                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16142                        }
16143                        if (mi == null) {
16144                            mi = new Debug.MemoryInfo();
16145                        }
16146                        if (dumpDetails || (!brief && !oomOnly)) {
16147                            Debug.getMemoryInfo(pid, mi);
16148                        } else {
16149                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16150                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16151                        }
16152                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16153                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16154                        if (isCheckinRequest) {
16155                            pw.println();
16156                        }
16157                    }
16158                    return;
16159                }
16160            }
16161            pw.println("No process found for: " + args[opti]);
16162            return;
16163        }
16164
16165        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16166            dumpDetails = true;
16167        }
16168
16169        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16170
16171        String[] innerArgs = new String[args.length-opti];
16172        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16173
16174        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16175        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16176        long nativePss = 0;
16177        long nativeSwapPss = 0;
16178        long dalvikPss = 0;
16179        long dalvikSwapPss = 0;
16180        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16181                EmptyArray.LONG;
16182        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16183                EmptyArray.LONG;
16184        long otherPss = 0;
16185        long otherSwapPss = 0;
16186        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16187        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16188
16189        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16190        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16191        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16192                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16193
16194        long totalPss = 0;
16195        long totalSwapPss = 0;
16196        long cachedPss = 0;
16197        long cachedSwapPss = 0;
16198        boolean hasSwapPss = false;
16199
16200        Debug.MemoryInfo mi = null;
16201        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16202            final ProcessRecord r = procs.get(i);
16203            final IApplicationThread thread;
16204            final int pid;
16205            final int oomAdj;
16206            final boolean hasActivities;
16207            synchronized (this) {
16208                thread = r.thread;
16209                pid = r.pid;
16210                oomAdj = r.getSetAdjWithServices();
16211                hasActivities = r.activities.size() > 0;
16212            }
16213            if (thread != null) {
16214                if (!isCheckinRequest && dumpDetails) {
16215                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16216                }
16217                if (mi == null) {
16218                    mi = new Debug.MemoryInfo();
16219                }
16220                if (dumpDetails || (!brief && !oomOnly)) {
16221                    Debug.getMemoryInfo(pid, mi);
16222                    hasSwapPss = mi.hasSwappedOutPss;
16223                } else {
16224                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16225                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16226                }
16227                if (dumpDetails) {
16228                    if (localOnly) {
16229                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16230                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16231                        if (isCheckinRequest) {
16232                            pw.println();
16233                        }
16234                    } else {
16235                        pw.flush();
16236                        try {
16237                            TransferPipe tp = new TransferPipe();
16238                            try {
16239                                thread.dumpMemInfo(tp.getWriteFd(),
16240                                        mi, isCheckinRequest, dumpFullDetails,
16241                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16242                                tp.go(fd);
16243                            } finally {
16244                                tp.kill();
16245                            }
16246                        } catch (IOException e) {
16247                            if (!isCheckinRequest) {
16248                                pw.println("Got IoException!");
16249                                pw.flush();
16250                            }
16251                        } catch (RemoteException e) {
16252                            if (!isCheckinRequest) {
16253                                pw.println("Got RemoteException!");
16254                                pw.flush();
16255                            }
16256                        }
16257                    }
16258                }
16259
16260                final long myTotalPss = mi.getTotalPss();
16261                final long myTotalUss = mi.getTotalUss();
16262                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16263
16264                synchronized (this) {
16265                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16266                        // Record this for posterity if the process has been stable.
16267                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16268                    }
16269                }
16270
16271                if (!isCheckinRequest && mi != null) {
16272                    totalPss += myTotalPss;
16273                    totalSwapPss += myTotalSwapPss;
16274                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16275                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16276                            myTotalSwapPss, pid, hasActivities);
16277                    procMems.add(pssItem);
16278                    procMemsMap.put(pid, pssItem);
16279
16280                    nativePss += mi.nativePss;
16281                    nativeSwapPss += mi.nativeSwappedOutPss;
16282                    dalvikPss += mi.dalvikPss;
16283                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16284                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16285                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16286                        dalvikSubitemSwapPss[j] +=
16287                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16288                    }
16289                    otherPss += mi.otherPss;
16290                    otherSwapPss += mi.otherSwappedOutPss;
16291                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16292                        long mem = mi.getOtherPss(j);
16293                        miscPss[j] += mem;
16294                        otherPss -= mem;
16295                        mem = mi.getOtherSwappedOutPss(j);
16296                        miscSwapPss[j] += mem;
16297                        otherSwapPss -= mem;
16298                    }
16299
16300                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16301                        cachedPss += myTotalPss;
16302                        cachedSwapPss += myTotalSwapPss;
16303                    }
16304
16305                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16306                        if (oomIndex == (oomPss.length - 1)
16307                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16308                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16309                            oomPss[oomIndex] += myTotalPss;
16310                            oomSwapPss[oomIndex] += myTotalSwapPss;
16311                            if (oomProcs[oomIndex] == null) {
16312                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16313                            }
16314                            oomProcs[oomIndex].add(pssItem);
16315                            break;
16316                        }
16317                    }
16318                }
16319            }
16320        }
16321
16322        long nativeProcTotalPss = 0;
16323
16324        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16325            // If we are showing aggregations, also look for native processes to
16326            // include so that our aggregations are more accurate.
16327            updateCpuStatsNow();
16328            mi = null;
16329            synchronized (mProcessCpuTracker) {
16330                final int N = mProcessCpuTracker.countStats();
16331                for (int i=0; i<N; i++) {
16332                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16333                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16334                        if (mi == null) {
16335                            mi = new Debug.MemoryInfo();
16336                        }
16337                        if (!brief && !oomOnly) {
16338                            Debug.getMemoryInfo(st.pid, mi);
16339                        } else {
16340                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16341                            mi.nativePrivateDirty = (int)tmpLong[0];
16342                        }
16343
16344                        final long myTotalPss = mi.getTotalPss();
16345                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16346                        totalPss += myTotalPss;
16347                        nativeProcTotalPss += myTotalPss;
16348
16349                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16350                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16351                        procMems.add(pssItem);
16352
16353                        nativePss += mi.nativePss;
16354                        nativeSwapPss += mi.nativeSwappedOutPss;
16355                        dalvikPss += mi.dalvikPss;
16356                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16357                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16358                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16359                            dalvikSubitemSwapPss[j] +=
16360                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16361                        }
16362                        otherPss += mi.otherPss;
16363                        otherSwapPss += mi.otherSwappedOutPss;
16364                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16365                            long mem = mi.getOtherPss(j);
16366                            miscPss[j] += mem;
16367                            otherPss -= mem;
16368                            mem = mi.getOtherSwappedOutPss(j);
16369                            miscSwapPss[j] += mem;
16370                            otherSwapPss -= mem;
16371                        }
16372                        oomPss[0] += myTotalPss;
16373                        oomSwapPss[0] += myTotalSwapPss;
16374                        if (oomProcs[0] == null) {
16375                            oomProcs[0] = new ArrayList<MemItem>();
16376                        }
16377                        oomProcs[0].add(pssItem);
16378                    }
16379                }
16380            }
16381
16382            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16383
16384            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16385            final MemItem dalvikItem =
16386                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16387            if (dalvikSubitemPss.length > 0) {
16388                dalvikItem.subitems = new ArrayList<MemItem>();
16389                for (int j=0; j<dalvikSubitemPss.length; j++) {
16390                    final String name = Debug.MemoryInfo.getOtherLabel(
16391                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16392                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16393                                    dalvikSubitemSwapPss[j], j));
16394                }
16395            }
16396            catMems.add(dalvikItem);
16397            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16398            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16399                String label = Debug.MemoryInfo.getOtherLabel(j);
16400                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16401            }
16402
16403            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16404            for (int j=0; j<oomPss.length; j++) {
16405                if (oomPss[j] != 0) {
16406                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16407                            : DUMP_MEM_OOM_LABEL[j];
16408                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16409                            DUMP_MEM_OOM_ADJ[j]);
16410                    item.subitems = oomProcs[j];
16411                    oomMems.add(item);
16412                }
16413            }
16414
16415            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16416            if (!brief && !oomOnly && !isCompact) {
16417                pw.println();
16418                pw.println("Total PSS by process:");
16419                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16420                pw.println();
16421            }
16422            if (!isCompact) {
16423                pw.println("Total PSS by OOM adjustment:");
16424            }
16425            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16426            if (!brief && !oomOnly) {
16427                PrintWriter out = categoryPw != null ? categoryPw : pw;
16428                if (!isCompact) {
16429                    out.println();
16430                    out.println("Total PSS by category:");
16431                }
16432                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16433            }
16434            if (!isCompact) {
16435                pw.println();
16436            }
16437            MemInfoReader memInfo = new MemInfoReader();
16438            memInfo.readMemInfo();
16439            if (nativeProcTotalPss > 0) {
16440                synchronized (this) {
16441                    final long cachedKb = memInfo.getCachedSizeKb();
16442                    final long freeKb = memInfo.getFreeSizeKb();
16443                    final long zramKb = memInfo.getZramTotalSizeKb();
16444                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16445                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16446                            kernelKb*1024, nativeProcTotalPss*1024);
16447                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16448                            nativeProcTotalPss);
16449                }
16450            }
16451            if (!brief) {
16452                if (!isCompact) {
16453                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16454                    pw.print(" (status ");
16455                    switch (mLastMemoryLevel) {
16456                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16457                            pw.println("normal)");
16458                            break;
16459                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16460                            pw.println("moderate)");
16461                            break;
16462                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16463                            pw.println("low)");
16464                            break;
16465                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16466                            pw.println("critical)");
16467                            break;
16468                        default:
16469                            pw.print(mLastMemoryLevel);
16470                            pw.println(")");
16471                            break;
16472                    }
16473                    pw.print(" Free RAM: ");
16474                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16475                            + memInfo.getFreeSizeKb()));
16476                    pw.print(" (");
16477                    pw.print(stringifyKBSize(cachedPss));
16478                    pw.print(" cached pss + ");
16479                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16480                    pw.print(" cached kernel + ");
16481                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16482                    pw.println(" free)");
16483                } else {
16484                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16485                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16486                            + memInfo.getFreeSizeKb()); pw.print(",");
16487                    pw.println(totalPss - cachedPss);
16488                }
16489            }
16490            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16491                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16492                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16493            if (!isCompact) {
16494                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16495                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16496                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16497                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16498                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16499            } else {
16500                pw.print("lostram,"); pw.println(lostRAM);
16501            }
16502            if (!brief) {
16503                if (memInfo.getZramTotalSizeKb() != 0) {
16504                    if (!isCompact) {
16505                        pw.print("     ZRAM: ");
16506                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16507                                pw.print(" physical used for ");
16508                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16509                                        - memInfo.getSwapFreeSizeKb()));
16510                                pw.print(" in swap (");
16511                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16512                                pw.println(" total swap)");
16513                    } else {
16514                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16515                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16516                                pw.println(memInfo.getSwapFreeSizeKb());
16517                    }
16518                }
16519                final long[] ksm = getKsmInfo();
16520                if (!isCompact) {
16521                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16522                            || ksm[KSM_VOLATILE] != 0) {
16523                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16524                                pw.print(" saved from shared ");
16525                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16526                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16527                                pw.print(" unshared; ");
16528                                pw.print(stringifyKBSize(
16529                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16530                    }
16531                    pw.print("   Tuning: ");
16532                    pw.print(ActivityManager.staticGetMemoryClass());
16533                    pw.print(" (large ");
16534                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16535                    pw.print("), oom ");
16536                    pw.print(stringifySize(
16537                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16538                    pw.print(", restore limit ");
16539                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16540                    if (ActivityManager.isLowRamDeviceStatic()) {
16541                        pw.print(" (low-ram)");
16542                    }
16543                    if (ActivityManager.isHighEndGfx()) {
16544                        pw.print(" (high-end-gfx)");
16545                    }
16546                    pw.println();
16547                } else {
16548                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16549                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16550                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16551                    pw.print("tuning,");
16552                    pw.print(ActivityManager.staticGetMemoryClass());
16553                    pw.print(',');
16554                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16555                    pw.print(',');
16556                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16557                    if (ActivityManager.isLowRamDeviceStatic()) {
16558                        pw.print(",low-ram");
16559                    }
16560                    if (ActivityManager.isHighEndGfx()) {
16561                        pw.print(",high-end-gfx");
16562                    }
16563                    pw.println();
16564                }
16565            }
16566        }
16567    }
16568
16569    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16570            long memtrack, String name) {
16571        sb.append("  ");
16572        sb.append(ProcessList.makeOomAdjString(oomAdj));
16573        sb.append(' ');
16574        sb.append(ProcessList.makeProcStateString(procState));
16575        sb.append(' ');
16576        ProcessList.appendRamKb(sb, pss);
16577        sb.append(": ");
16578        sb.append(name);
16579        if (memtrack > 0) {
16580            sb.append(" (");
16581            sb.append(stringifyKBSize(memtrack));
16582            sb.append(" memtrack)");
16583        }
16584    }
16585
16586    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16587        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16588        sb.append(" (pid ");
16589        sb.append(mi.pid);
16590        sb.append(") ");
16591        sb.append(mi.adjType);
16592        sb.append('\n');
16593        if (mi.adjReason != null) {
16594            sb.append("                      ");
16595            sb.append(mi.adjReason);
16596            sb.append('\n');
16597        }
16598    }
16599
16600    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16601        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16602        for (int i=0, N=memInfos.size(); i<N; i++) {
16603            ProcessMemInfo mi = memInfos.get(i);
16604            infoMap.put(mi.pid, mi);
16605        }
16606        updateCpuStatsNow();
16607        long[] memtrackTmp = new long[1];
16608        final List<ProcessCpuTracker.Stats> stats;
16609        // Get a list of Stats that have vsize > 0
16610        synchronized (mProcessCpuTracker) {
16611            stats = mProcessCpuTracker.getStats((st) -> {
16612                return st.vsize > 0;
16613            });
16614        }
16615        final int statsCount = stats.size();
16616        for (int i = 0; i < statsCount; i++) {
16617            ProcessCpuTracker.Stats st = stats.get(i);
16618            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16619            if (pss > 0) {
16620                if (infoMap.indexOfKey(st.pid) < 0) {
16621                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16622                            ProcessList.NATIVE_ADJ, -1, "native", null);
16623                    mi.pss = pss;
16624                    mi.memtrack = memtrackTmp[0];
16625                    memInfos.add(mi);
16626                }
16627            }
16628        }
16629
16630        long totalPss = 0;
16631        long totalMemtrack = 0;
16632        for (int i=0, N=memInfos.size(); i<N; i++) {
16633            ProcessMemInfo mi = memInfos.get(i);
16634            if (mi.pss == 0) {
16635                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16636                mi.memtrack = memtrackTmp[0];
16637            }
16638            totalPss += mi.pss;
16639            totalMemtrack += mi.memtrack;
16640        }
16641        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16642            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16643                if (lhs.oomAdj != rhs.oomAdj) {
16644                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16645                }
16646                if (lhs.pss != rhs.pss) {
16647                    return lhs.pss < rhs.pss ? 1 : -1;
16648                }
16649                return 0;
16650            }
16651        });
16652
16653        StringBuilder tag = new StringBuilder(128);
16654        StringBuilder stack = new StringBuilder(128);
16655        tag.append("Low on memory -- ");
16656        appendMemBucket(tag, totalPss, "total", false);
16657        appendMemBucket(stack, totalPss, "total", true);
16658
16659        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16660        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16661        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16662
16663        boolean firstLine = true;
16664        int lastOomAdj = Integer.MIN_VALUE;
16665        long extraNativeRam = 0;
16666        long extraNativeMemtrack = 0;
16667        long cachedPss = 0;
16668        for (int i=0, N=memInfos.size(); i<N; i++) {
16669            ProcessMemInfo mi = memInfos.get(i);
16670
16671            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16672                cachedPss += mi.pss;
16673            }
16674
16675            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16676                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16677                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16678                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16679                if (lastOomAdj != mi.oomAdj) {
16680                    lastOomAdj = mi.oomAdj;
16681                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16682                        tag.append(" / ");
16683                    }
16684                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16685                        if (firstLine) {
16686                            stack.append(":");
16687                            firstLine = false;
16688                        }
16689                        stack.append("\n\t at ");
16690                    } else {
16691                        stack.append("$");
16692                    }
16693                } else {
16694                    tag.append(" ");
16695                    stack.append("$");
16696                }
16697                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16698                    appendMemBucket(tag, mi.pss, mi.name, false);
16699                }
16700                appendMemBucket(stack, mi.pss, mi.name, true);
16701                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16702                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16703                    stack.append("(");
16704                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16705                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16706                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16707                            stack.append(":");
16708                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16709                        }
16710                    }
16711                    stack.append(")");
16712                }
16713            }
16714
16715            appendMemInfo(fullNativeBuilder, mi);
16716            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16717                // The short form only has native processes that are >= 512K.
16718                if (mi.pss >= 512) {
16719                    appendMemInfo(shortNativeBuilder, mi);
16720                } else {
16721                    extraNativeRam += mi.pss;
16722                    extraNativeMemtrack += mi.memtrack;
16723                }
16724            } else {
16725                // Short form has all other details, but if we have collected RAM
16726                // from smaller native processes let's dump a summary of that.
16727                if (extraNativeRam > 0) {
16728                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16729                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16730                    shortNativeBuilder.append('\n');
16731                    extraNativeRam = 0;
16732                }
16733                appendMemInfo(fullJavaBuilder, mi);
16734            }
16735        }
16736
16737        fullJavaBuilder.append("           ");
16738        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16739        fullJavaBuilder.append(": TOTAL");
16740        if (totalMemtrack > 0) {
16741            fullJavaBuilder.append(" (");
16742            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16743            fullJavaBuilder.append(" memtrack)");
16744        } else {
16745        }
16746        fullJavaBuilder.append("\n");
16747
16748        MemInfoReader memInfo = new MemInfoReader();
16749        memInfo.readMemInfo();
16750        final long[] infos = memInfo.getRawInfo();
16751
16752        StringBuilder memInfoBuilder = new StringBuilder(1024);
16753        Debug.getMemInfo(infos);
16754        memInfoBuilder.append("  MemInfo: ");
16755        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16756        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16757        memInfoBuilder.append(stringifyKBSize(
16758                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16759        memInfoBuilder.append(stringifyKBSize(
16760                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16761        memInfoBuilder.append(stringifyKBSize(
16762                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16763        memInfoBuilder.append("           ");
16764        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16765        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16766        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16767        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16768        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16769            memInfoBuilder.append("  ZRAM: ");
16770            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16771            memInfoBuilder.append(" RAM, ");
16772            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16773            memInfoBuilder.append(" swap total, ");
16774            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16775            memInfoBuilder.append(" swap free\n");
16776        }
16777        final long[] ksm = getKsmInfo();
16778        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16779                || ksm[KSM_VOLATILE] != 0) {
16780            memInfoBuilder.append("  KSM: ");
16781            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16782            memInfoBuilder.append(" saved from shared ");
16783            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16784            memInfoBuilder.append("\n       ");
16785            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16786            memInfoBuilder.append(" unshared; ");
16787            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16788            memInfoBuilder.append(" volatile\n");
16789        }
16790        memInfoBuilder.append("  Free RAM: ");
16791        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16792                + memInfo.getFreeSizeKb()));
16793        memInfoBuilder.append("\n");
16794        memInfoBuilder.append("  Used RAM: ");
16795        memInfoBuilder.append(stringifyKBSize(
16796                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16797        memInfoBuilder.append("\n");
16798        memInfoBuilder.append("  Lost RAM: ");
16799        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16800                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16801                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16802        memInfoBuilder.append("\n");
16803        Slog.i(TAG, "Low on memory:");
16804        Slog.i(TAG, shortNativeBuilder.toString());
16805        Slog.i(TAG, fullJavaBuilder.toString());
16806        Slog.i(TAG, memInfoBuilder.toString());
16807
16808        StringBuilder dropBuilder = new StringBuilder(1024);
16809        /*
16810        StringWriter oomSw = new StringWriter();
16811        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16812        StringWriter catSw = new StringWriter();
16813        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16814        String[] emptyArgs = new String[] { };
16815        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16816        oomPw.flush();
16817        String oomString = oomSw.toString();
16818        */
16819        dropBuilder.append("Low on memory:");
16820        dropBuilder.append(stack);
16821        dropBuilder.append('\n');
16822        dropBuilder.append(fullNativeBuilder);
16823        dropBuilder.append(fullJavaBuilder);
16824        dropBuilder.append('\n');
16825        dropBuilder.append(memInfoBuilder);
16826        dropBuilder.append('\n');
16827        /*
16828        dropBuilder.append(oomString);
16829        dropBuilder.append('\n');
16830        */
16831        StringWriter catSw = new StringWriter();
16832        synchronized (ActivityManagerService.this) {
16833            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16834            String[] emptyArgs = new String[] { };
16835            catPw.println();
16836            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16837            catPw.println();
16838            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16839                    false, null).dumpLocked();
16840            catPw.println();
16841            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16842            catPw.flush();
16843        }
16844        dropBuilder.append(catSw.toString());
16845        addErrorToDropBox("lowmem", null, "system_server", null,
16846                null, tag.toString(), dropBuilder.toString(), null, null);
16847        //Slog.i(TAG, "Sent to dropbox:");
16848        //Slog.i(TAG, dropBuilder.toString());
16849        synchronized (ActivityManagerService.this) {
16850            long now = SystemClock.uptimeMillis();
16851            if (mLastMemUsageReportTime < now) {
16852                mLastMemUsageReportTime = now;
16853            }
16854        }
16855    }
16856
16857    /**
16858     * Searches array of arguments for the specified string
16859     * @param args array of argument strings
16860     * @param value value to search for
16861     * @return true if the value is contained in the array
16862     */
16863    private static boolean scanArgs(String[] args, String value) {
16864        if (args != null) {
16865            for (String arg : args) {
16866                if (value.equals(arg)) {
16867                    return true;
16868                }
16869            }
16870        }
16871        return false;
16872    }
16873
16874    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16875            ContentProviderRecord cpr, boolean always) {
16876        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16877
16878        if (!inLaunching || always) {
16879            synchronized (cpr) {
16880                cpr.launchingApp = null;
16881                cpr.notifyAll();
16882            }
16883            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16884            String names[] = cpr.info.authority.split(";");
16885            for (int j = 0; j < names.length; j++) {
16886                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16887            }
16888        }
16889
16890        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16891            ContentProviderConnection conn = cpr.connections.get(i);
16892            if (conn.waiting) {
16893                // If this connection is waiting for the provider, then we don't
16894                // need to mess with its process unless we are always removing
16895                // or for some reason the provider is not currently launching.
16896                if (inLaunching && !always) {
16897                    continue;
16898                }
16899            }
16900            ProcessRecord capp = conn.client;
16901            conn.dead = true;
16902            if (conn.stableCount > 0) {
16903                if (!capp.persistent && capp.thread != null
16904                        && capp.pid != 0
16905                        && capp.pid != MY_PID) {
16906                    capp.kill("depends on provider "
16907                            + cpr.name.flattenToShortString()
16908                            + " in dying proc " + (proc != null ? proc.processName : "??")
16909                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16910                }
16911            } else if (capp.thread != null && conn.provider.provider != null) {
16912                try {
16913                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16914                } catch (RemoteException e) {
16915                }
16916                // In the protocol here, we don't expect the client to correctly
16917                // clean up this connection, we'll just remove it.
16918                cpr.connections.remove(i);
16919                if (conn.client.conProviders.remove(conn)) {
16920                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16921                }
16922            }
16923        }
16924
16925        if (inLaunching && always) {
16926            mLaunchingProviders.remove(cpr);
16927        }
16928        return inLaunching;
16929    }
16930
16931    /**
16932     * Main code for cleaning up a process when it has gone away.  This is
16933     * called both as a result of the process dying, or directly when stopping
16934     * a process when running in single process mode.
16935     *
16936     * @return Returns true if the given process has been restarted, so the
16937     * app that was passed in must remain on the process lists.
16938     */
16939    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16940            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16941        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16942        if (index >= 0) {
16943            removeLruProcessLocked(app);
16944            ProcessList.remove(app.pid);
16945        }
16946
16947        mProcessesToGc.remove(app);
16948        mPendingPssProcesses.remove(app);
16949
16950        // Dismiss any open dialogs.
16951        if (app.crashDialog != null && !app.forceCrashReport) {
16952            app.crashDialog.dismiss();
16953            app.crashDialog = null;
16954        }
16955        if (app.anrDialog != null) {
16956            app.anrDialog.dismiss();
16957            app.anrDialog = null;
16958        }
16959        if (app.waitDialog != null) {
16960            app.waitDialog.dismiss();
16961            app.waitDialog = null;
16962        }
16963
16964        app.crashing = false;
16965        app.notResponding = false;
16966
16967        app.resetPackageList(mProcessStats);
16968        app.unlinkDeathRecipient();
16969        app.makeInactive(mProcessStats);
16970        app.waitingToKill = null;
16971        app.forcingToForeground = null;
16972        updateProcessForegroundLocked(app, false, false);
16973        app.foregroundActivities = false;
16974        app.hasShownUi = false;
16975        app.treatLikeActivity = false;
16976        app.hasAboveClient = false;
16977        app.hasClientActivities = false;
16978
16979        mServices.killServicesLocked(app, allowRestart);
16980
16981        boolean restart = false;
16982
16983        // Remove published content providers.
16984        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16985            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16986            final boolean always = app.bad || !allowRestart;
16987            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16988            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16989                // We left the provider in the launching list, need to
16990                // restart it.
16991                restart = true;
16992            }
16993
16994            cpr.provider = null;
16995            cpr.proc = null;
16996        }
16997        app.pubProviders.clear();
16998
16999        // Take care of any launching providers waiting for this process.
17000        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17001            restart = true;
17002        }
17003
17004        // Unregister from connected content providers.
17005        if (!app.conProviders.isEmpty()) {
17006            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17007                ContentProviderConnection conn = app.conProviders.get(i);
17008                conn.provider.connections.remove(conn);
17009                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17010                        conn.provider.name);
17011            }
17012            app.conProviders.clear();
17013        }
17014
17015        // At this point there may be remaining entries in mLaunchingProviders
17016        // where we were the only one waiting, so they are no longer of use.
17017        // Look for these and clean up if found.
17018        // XXX Commented out for now.  Trying to figure out a way to reproduce
17019        // the actual situation to identify what is actually going on.
17020        if (false) {
17021            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17022                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17023                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17024                    synchronized (cpr) {
17025                        cpr.launchingApp = null;
17026                        cpr.notifyAll();
17027                    }
17028                }
17029            }
17030        }
17031
17032        skipCurrentReceiverLocked(app);
17033
17034        // Unregister any receivers.
17035        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17036            removeReceiverLocked(app.receivers.valueAt(i));
17037        }
17038        app.receivers.clear();
17039
17040        // If the app is undergoing backup, tell the backup manager about it
17041        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17042            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17043                    + mBackupTarget.appInfo + " died during backup");
17044            mHandler.post(new Runnable() {
17045                @Override
17046                public void run(){
17047                    try {
17048                        IBackupManager bm = IBackupManager.Stub.asInterface(
17049                                ServiceManager.getService(Context.BACKUP_SERVICE));
17050                        bm.agentDisconnected(app.info.packageName);
17051                    } catch (RemoteException e) {
17052                        // can't happen; backup manager is local
17053                    }
17054                }
17055            });
17056        }
17057
17058        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17059            ProcessChangeItem item = mPendingProcessChanges.get(i);
17060            if (item.pid == app.pid) {
17061                mPendingProcessChanges.remove(i);
17062                mAvailProcessChanges.add(item);
17063            }
17064        }
17065        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17066                null).sendToTarget();
17067
17068        // If the caller is restarting this app, then leave it in its
17069        // current lists and let the caller take care of it.
17070        if (restarting) {
17071            return false;
17072        }
17073
17074        if (!app.persistent || app.isolated) {
17075            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17076                    "Removing non-persistent process during cleanup: " + app);
17077            if (!replacingPid) {
17078                removeProcessNameLocked(app.processName, app.uid, app);
17079            }
17080            if (mHeavyWeightProcess == app) {
17081                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17082                        mHeavyWeightProcess.userId, 0));
17083                mHeavyWeightProcess = null;
17084            }
17085        } else if (!app.removed) {
17086            // This app is persistent, so we need to keep its record around.
17087            // If it is not already on the pending app list, add it there
17088            // and start a new process for it.
17089            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17090                mPersistentStartingProcesses.add(app);
17091                restart = true;
17092            }
17093        }
17094        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17095                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17096        mProcessesOnHold.remove(app);
17097
17098        if (app == mHomeProcess) {
17099            mHomeProcess = null;
17100        }
17101        if (app == mPreviousProcess) {
17102            mPreviousProcess = null;
17103        }
17104
17105        if (restart && !app.isolated) {
17106            // We have components that still need to be running in the
17107            // process, so re-launch it.
17108            if (index < 0) {
17109                ProcessList.remove(app.pid);
17110            }
17111            addProcessNameLocked(app);
17112            startProcessLocked(app, "restart", app.processName);
17113            return true;
17114        } else if (app.pid > 0 && app.pid != MY_PID) {
17115            // Goodbye!
17116            boolean removed;
17117            synchronized (mPidsSelfLocked) {
17118                mPidsSelfLocked.remove(app.pid);
17119                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17120            }
17121            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17122            if (app.isolated) {
17123                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17124            }
17125            app.setPid(0);
17126        }
17127        return false;
17128    }
17129
17130    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17131        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17132            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17133            if (cpr.launchingApp == app) {
17134                return true;
17135            }
17136        }
17137        return false;
17138    }
17139
17140    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17141        // Look through the content providers we are waiting to have launched,
17142        // and if any run in this process then either schedule a restart of
17143        // the process or kill the client waiting for it if this process has
17144        // gone bad.
17145        boolean restart = false;
17146        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17147            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17148            if (cpr.launchingApp == app) {
17149                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17150                    restart = true;
17151                } else {
17152                    removeDyingProviderLocked(app, cpr, true);
17153                }
17154            }
17155        }
17156        return restart;
17157    }
17158
17159    // =========================================================
17160    // SERVICES
17161    // =========================================================
17162
17163    @Override
17164    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17165            int flags) {
17166        enforceNotIsolatedCaller("getServices");
17167        synchronized (this) {
17168            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17169        }
17170    }
17171
17172    @Override
17173    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17174        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17175        synchronized (this) {
17176            return mServices.getRunningServiceControlPanelLocked(name);
17177        }
17178    }
17179
17180    @Override
17181    public ComponentName startService(IApplicationThread caller, Intent service,
17182            String resolvedType, String callingPackage, int userId)
17183            throws TransactionTooLargeException {
17184        enforceNotIsolatedCaller("startService");
17185        // Refuse possible leaked file descriptors
17186        if (service != null && service.hasFileDescriptors() == true) {
17187            throw new IllegalArgumentException("File descriptors passed in Intent");
17188        }
17189
17190        if (callingPackage == null) {
17191            throw new IllegalArgumentException("callingPackage cannot be null");
17192        }
17193
17194        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17195                "startService: " + service + " type=" + resolvedType);
17196        synchronized(this) {
17197            final int callingPid = Binder.getCallingPid();
17198            final int callingUid = Binder.getCallingUid();
17199            final long origId = Binder.clearCallingIdentity();
17200            ComponentName res = mServices.startServiceLocked(caller, service,
17201                    resolvedType, callingPid, callingUid, callingPackage, userId);
17202            Binder.restoreCallingIdentity(origId);
17203            return res;
17204        }
17205    }
17206
17207    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17208            String callingPackage, int userId)
17209            throws TransactionTooLargeException {
17210        synchronized(this) {
17211            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17212                    "startServiceInPackage: " + service + " type=" + resolvedType);
17213            final long origId = Binder.clearCallingIdentity();
17214            ComponentName res = mServices.startServiceLocked(null, service,
17215                    resolvedType, -1, uid, callingPackage, userId);
17216            Binder.restoreCallingIdentity(origId);
17217            return res;
17218        }
17219    }
17220
17221    @Override
17222    public int stopService(IApplicationThread caller, Intent service,
17223            String resolvedType, int userId) {
17224        enforceNotIsolatedCaller("stopService");
17225        // Refuse possible leaked file descriptors
17226        if (service != null && service.hasFileDescriptors() == true) {
17227            throw new IllegalArgumentException("File descriptors passed in Intent");
17228        }
17229
17230        synchronized(this) {
17231            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17232        }
17233    }
17234
17235    @Override
17236    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17237        enforceNotIsolatedCaller("peekService");
17238        // Refuse possible leaked file descriptors
17239        if (service != null && service.hasFileDescriptors() == true) {
17240            throw new IllegalArgumentException("File descriptors passed in Intent");
17241        }
17242
17243        if (callingPackage == null) {
17244            throw new IllegalArgumentException("callingPackage cannot be null");
17245        }
17246
17247        synchronized(this) {
17248            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17249        }
17250    }
17251
17252    @Override
17253    public boolean stopServiceToken(ComponentName className, IBinder token,
17254            int startId) {
17255        synchronized(this) {
17256            return mServices.stopServiceTokenLocked(className, token, startId);
17257        }
17258    }
17259
17260    @Override
17261    public void setServiceForeground(ComponentName className, IBinder token,
17262            int id, Notification notification, int flags) {
17263        synchronized(this) {
17264            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17265        }
17266    }
17267
17268    @Override
17269    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17270            boolean requireFull, String name, String callerPackage) {
17271        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17272                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17273    }
17274
17275    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17276            String className, int flags) {
17277        boolean result = false;
17278        // For apps that don't have pre-defined UIDs, check for permission
17279        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17280            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17281                if (ActivityManager.checkUidPermission(
17282                        INTERACT_ACROSS_USERS,
17283                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17284                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17285                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17286                            + " requests FLAG_SINGLE_USER, but app does not hold "
17287                            + INTERACT_ACROSS_USERS;
17288                    Slog.w(TAG, msg);
17289                    throw new SecurityException(msg);
17290                }
17291                // Permission passed
17292                result = true;
17293            }
17294        } else if ("system".equals(componentProcessName)) {
17295            result = true;
17296        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17297            // Phone app and persistent apps are allowed to export singleuser providers.
17298            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17299                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17300        }
17301        if (DEBUG_MU) Slog.v(TAG_MU,
17302                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17303                + Integer.toHexString(flags) + ") = " + result);
17304        return result;
17305    }
17306
17307    /**
17308     * Checks to see if the caller is in the same app as the singleton
17309     * component, or the component is in a special app. It allows special apps
17310     * to export singleton components but prevents exporting singleton
17311     * components for regular apps.
17312     */
17313    boolean isValidSingletonCall(int callingUid, int componentUid) {
17314        int componentAppId = UserHandle.getAppId(componentUid);
17315        return UserHandle.isSameApp(callingUid, componentUid)
17316                || componentAppId == Process.SYSTEM_UID
17317                || componentAppId == Process.PHONE_UID
17318                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17319                        == PackageManager.PERMISSION_GRANTED;
17320    }
17321
17322    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17323            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17324            int userId) throws TransactionTooLargeException {
17325        enforceNotIsolatedCaller("bindService");
17326
17327        // Refuse possible leaked file descriptors
17328        if (service != null && service.hasFileDescriptors() == true) {
17329            throw new IllegalArgumentException("File descriptors passed in Intent");
17330        }
17331
17332        if (callingPackage == null) {
17333            throw new IllegalArgumentException("callingPackage cannot be null");
17334        }
17335
17336        synchronized(this) {
17337            return mServices.bindServiceLocked(caller, token, service,
17338                    resolvedType, connection, flags, callingPackage, userId);
17339        }
17340    }
17341
17342    public boolean unbindService(IServiceConnection connection) {
17343        synchronized (this) {
17344            return mServices.unbindServiceLocked(connection);
17345        }
17346    }
17347
17348    public void publishService(IBinder token, Intent intent, IBinder service) {
17349        // Refuse possible leaked file descriptors
17350        if (intent != null && intent.hasFileDescriptors() == true) {
17351            throw new IllegalArgumentException("File descriptors passed in Intent");
17352        }
17353
17354        synchronized(this) {
17355            if (!(token instanceof ServiceRecord)) {
17356                throw new IllegalArgumentException("Invalid service token");
17357            }
17358            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17359        }
17360    }
17361
17362    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17363        // Refuse possible leaked file descriptors
17364        if (intent != null && intent.hasFileDescriptors() == true) {
17365            throw new IllegalArgumentException("File descriptors passed in Intent");
17366        }
17367
17368        synchronized(this) {
17369            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17370        }
17371    }
17372
17373    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17374        synchronized(this) {
17375            if (!(token instanceof ServiceRecord)) {
17376                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17377                throw new IllegalArgumentException("Invalid service token");
17378            }
17379            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17380        }
17381    }
17382
17383    // =========================================================
17384    // BACKUP AND RESTORE
17385    // =========================================================
17386
17387    // Cause the target app to be launched if necessary and its backup agent
17388    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17389    // activity manager to announce its creation.
17390    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17391        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17392        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17393
17394        IPackageManager pm = AppGlobals.getPackageManager();
17395        ApplicationInfo app = null;
17396        try {
17397            app = pm.getApplicationInfo(packageName, 0, userId);
17398        } catch (RemoteException e) {
17399            // can't happen; package manager is process-local
17400        }
17401        if (app == null) {
17402            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17403            return false;
17404        }
17405
17406        synchronized(this) {
17407            // !!! TODO: currently no check here that we're already bound
17408            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17409            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17410            synchronized (stats) {
17411                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17412            }
17413
17414            // Backup agent is now in use, its package can't be stopped.
17415            try {
17416                AppGlobals.getPackageManager().setPackageStoppedState(
17417                        app.packageName, false, UserHandle.getUserId(app.uid));
17418            } catch (RemoteException e) {
17419            } catch (IllegalArgumentException e) {
17420                Slog.w(TAG, "Failed trying to unstop package "
17421                        + app.packageName + ": " + e);
17422            }
17423
17424            BackupRecord r = new BackupRecord(ss, app, backupMode);
17425            ComponentName hostingName =
17426                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17427                            ? new ComponentName(app.packageName, app.backupAgentName)
17428                            : new ComponentName("android", "FullBackupAgent");
17429            // startProcessLocked() returns existing proc's record if it's already running
17430            ProcessRecord proc = startProcessLocked(app.processName, app,
17431                    false, 0, "backup", hostingName, false, false, false);
17432            if (proc == null) {
17433                Slog.e(TAG, "Unable to start backup agent process " + r);
17434                return false;
17435            }
17436
17437            // If the app is a regular app (uid >= 10000) and not the system server or phone
17438            // process, etc, then mark it as being in full backup so that certain calls to the
17439            // process can be blocked. This is not reset to false anywhere because we kill the
17440            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17441            if (UserHandle.isApp(app.uid) &&
17442                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17443                proc.inFullBackup = true;
17444            }
17445            r.app = proc;
17446            mBackupTarget = r;
17447            mBackupAppName = app.packageName;
17448
17449            // Try not to kill the process during backup
17450            updateOomAdjLocked(proc);
17451
17452            // If the process is already attached, schedule the creation of the backup agent now.
17453            // If it is not yet live, this will be done when it attaches to the framework.
17454            if (proc.thread != null) {
17455                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17456                try {
17457                    proc.thread.scheduleCreateBackupAgent(app,
17458                            compatibilityInfoForPackageLocked(app), backupMode);
17459                } catch (RemoteException e) {
17460                    // Will time out on the backup manager side
17461                }
17462            } else {
17463                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17464            }
17465            // Invariants: at this point, the target app process exists and the application
17466            // is either already running or in the process of coming up.  mBackupTarget and
17467            // mBackupAppName describe the app, so that when it binds back to the AM we
17468            // know that it's scheduled for a backup-agent operation.
17469        }
17470
17471        return true;
17472    }
17473
17474    @Override
17475    public void clearPendingBackup() {
17476        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17477        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17478
17479        synchronized (this) {
17480            mBackupTarget = null;
17481            mBackupAppName = null;
17482        }
17483    }
17484
17485    // A backup agent has just come up
17486    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17487        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17488                + " = " + agent);
17489
17490        synchronized(this) {
17491            if (!agentPackageName.equals(mBackupAppName)) {
17492                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17493                return;
17494            }
17495        }
17496
17497        long oldIdent = Binder.clearCallingIdentity();
17498        try {
17499            IBackupManager bm = IBackupManager.Stub.asInterface(
17500                    ServiceManager.getService(Context.BACKUP_SERVICE));
17501            bm.agentConnected(agentPackageName, agent);
17502        } catch (RemoteException e) {
17503            // can't happen; the backup manager service is local
17504        } catch (Exception e) {
17505            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17506            e.printStackTrace();
17507        } finally {
17508            Binder.restoreCallingIdentity(oldIdent);
17509        }
17510    }
17511
17512    // done with this agent
17513    public void unbindBackupAgent(ApplicationInfo appInfo) {
17514        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17515        if (appInfo == null) {
17516            Slog.w(TAG, "unbind backup agent for null app");
17517            return;
17518        }
17519
17520        synchronized(this) {
17521            try {
17522                if (mBackupAppName == null) {
17523                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17524                    return;
17525                }
17526
17527                if (!mBackupAppName.equals(appInfo.packageName)) {
17528                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17529                    return;
17530                }
17531
17532                // Not backing this app up any more; reset its OOM adjustment
17533                final ProcessRecord proc = mBackupTarget.app;
17534                updateOomAdjLocked(proc);
17535
17536                // If the app crashed during backup, 'thread' will be null here
17537                if (proc.thread != null) {
17538                    try {
17539                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17540                                compatibilityInfoForPackageLocked(appInfo));
17541                    } catch (Exception e) {
17542                        Slog.e(TAG, "Exception when unbinding backup agent:");
17543                        e.printStackTrace();
17544                    }
17545                }
17546            } finally {
17547                mBackupTarget = null;
17548                mBackupAppName = null;
17549            }
17550        }
17551    }
17552    // =========================================================
17553    // BROADCASTS
17554    // =========================================================
17555
17556    boolean isPendingBroadcastProcessLocked(int pid) {
17557        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17558                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17559    }
17560
17561    void skipPendingBroadcastLocked(int pid) {
17562            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17563            for (BroadcastQueue queue : mBroadcastQueues) {
17564                queue.skipPendingBroadcastLocked(pid);
17565            }
17566    }
17567
17568    // The app just attached; send any pending broadcasts that it should receive
17569    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17570        boolean didSomething = false;
17571        for (BroadcastQueue queue : mBroadcastQueues) {
17572            didSomething |= queue.sendPendingBroadcastsLocked(app);
17573        }
17574        return didSomething;
17575    }
17576
17577    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17578            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17579        enforceNotIsolatedCaller("registerReceiver");
17580        ArrayList<Intent> stickyIntents = null;
17581        ProcessRecord callerApp = null;
17582        int callingUid;
17583        int callingPid;
17584        synchronized(this) {
17585            if (caller != null) {
17586                callerApp = getRecordForAppLocked(caller);
17587                if (callerApp == null) {
17588                    throw new SecurityException(
17589                            "Unable to find app for caller " + caller
17590                            + " (pid=" + Binder.getCallingPid()
17591                            + ") when registering receiver " + receiver);
17592                }
17593                if (callerApp.info.uid != Process.SYSTEM_UID &&
17594                        !callerApp.pkgList.containsKey(callerPackage) &&
17595                        !"android".equals(callerPackage)) {
17596                    throw new SecurityException("Given caller package " + callerPackage
17597                            + " is not running in process " + callerApp);
17598                }
17599                callingUid = callerApp.info.uid;
17600                callingPid = callerApp.pid;
17601            } else {
17602                callerPackage = null;
17603                callingUid = Binder.getCallingUid();
17604                callingPid = Binder.getCallingPid();
17605            }
17606
17607            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17608                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17609
17610            Iterator<String> actions = filter.actionsIterator();
17611            if (actions == null) {
17612                ArrayList<String> noAction = new ArrayList<String>(1);
17613                noAction.add(null);
17614                actions = noAction.iterator();
17615            }
17616
17617            // Collect stickies of users
17618            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17619            while (actions.hasNext()) {
17620                String action = actions.next();
17621                for (int id : userIds) {
17622                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17623                    if (stickies != null) {
17624                        ArrayList<Intent> intents = stickies.get(action);
17625                        if (intents != null) {
17626                            if (stickyIntents == null) {
17627                                stickyIntents = new ArrayList<Intent>();
17628                            }
17629                            stickyIntents.addAll(intents);
17630                        }
17631                    }
17632                }
17633            }
17634        }
17635
17636        ArrayList<Intent> allSticky = null;
17637        if (stickyIntents != null) {
17638            final ContentResolver resolver = mContext.getContentResolver();
17639            // Look for any matching sticky broadcasts...
17640            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17641                Intent intent = stickyIntents.get(i);
17642                // If intent has scheme "content", it will need to acccess
17643                // provider that needs to lock mProviderMap in ActivityThread
17644                // and also it may need to wait application response, so we
17645                // cannot lock ActivityManagerService here.
17646                if (filter.match(resolver, intent, true, TAG) >= 0) {
17647                    if (allSticky == null) {
17648                        allSticky = new ArrayList<Intent>();
17649                    }
17650                    allSticky.add(intent);
17651                }
17652            }
17653        }
17654
17655        // The first sticky in the list is returned directly back to the client.
17656        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17657        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17658        if (receiver == null) {
17659            return sticky;
17660        }
17661
17662        synchronized (this) {
17663            if (callerApp != null && (callerApp.thread == null
17664                    || callerApp.thread.asBinder() != caller.asBinder())) {
17665                // Original caller already died
17666                return null;
17667            }
17668            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17669            if (rl == null) {
17670                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17671                        userId, receiver);
17672                if (rl.app != null) {
17673                    rl.app.receivers.add(rl);
17674                } else {
17675                    try {
17676                        receiver.asBinder().linkToDeath(rl, 0);
17677                    } catch (RemoteException e) {
17678                        return sticky;
17679                    }
17680                    rl.linkedToDeath = true;
17681                }
17682                mRegisteredReceivers.put(receiver.asBinder(), rl);
17683            } else if (rl.uid != callingUid) {
17684                throw new IllegalArgumentException(
17685                        "Receiver requested to register for uid " + callingUid
17686                        + " was previously registered for uid " + rl.uid);
17687            } else if (rl.pid != callingPid) {
17688                throw new IllegalArgumentException(
17689                        "Receiver requested to register for pid " + callingPid
17690                        + " was previously registered for pid " + rl.pid);
17691            } else if (rl.userId != userId) {
17692                throw new IllegalArgumentException(
17693                        "Receiver requested to register for user " + userId
17694                        + " was previously registered for user " + rl.userId);
17695            }
17696            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17697                    permission, callingUid, userId);
17698            rl.add(bf);
17699            if (!bf.debugCheck()) {
17700                Slog.w(TAG, "==> For Dynamic broadcast");
17701            }
17702            mReceiverResolver.addFilter(bf);
17703
17704            // Enqueue broadcasts for all existing stickies that match
17705            // this filter.
17706            if (allSticky != null) {
17707                ArrayList receivers = new ArrayList();
17708                receivers.add(bf);
17709
17710                final int stickyCount = allSticky.size();
17711                for (int i = 0; i < stickyCount; i++) {
17712                    Intent intent = allSticky.get(i);
17713                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17714                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17715                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17716                            null, 0, null, null, false, true, true, -1);
17717                    queue.enqueueParallelBroadcastLocked(r);
17718                    queue.scheduleBroadcastsLocked();
17719                }
17720            }
17721
17722            return sticky;
17723        }
17724    }
17725
17726    public void unregisterReceiver(IIntentReceiver receiver) {
17727        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17728
17729        final long origId = Binder.clearCallingIdentity();
17730        try {
17731            boolean doTrim = false;
17732
17733            synchronized(this) {
17734                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17735                if (rl != null) {
17736                    final BroadcastRecord r = rl.curBroadcast;
17737                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17738                        final boolean doNext = r.queue.finishReceiverLocked(
17739                                r, r.resultCode, r.resultData, r.resultExtras,
17740                                r.resultAbort, false);
17741                        if (doNext) {
17742                            doTrim = true;
17743                            r.queue.processNextBroadcast(false);
17744                        }
17745                    }
17746
17747                    if (rl.app != null) {
17748                        rl.app.receivers.remove(rl);
17749                    }
17750                    removeReceiverLocked(rl);
17751                    if (rl.linkedToDeath) {
17752                        rl.linkedToDeath = false;
17753                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17754                    }
17755                }
17756            }
17757
17758            // If we actually concluded any broadcasts, we might now be able
17759            // to trim the recipients' apps from our working set
17760            if (doTrim) {
17761                trimApplications();
17762                return;
17763            }
17764
17765        } finally {
17766            Binder.restoreCallingIdentity(origId);
17767        }
17768    }
17769
17770    void removeReceiverLocked(ReceiverList rl) {
17771        mRegisteredReceivers.remove(rl.receiver.asBinder());
17772        for (int i = rl.size() - 1; i >= 0; i--) {
17773            mReceiverResolver.removeFilter(rl.get(i));
17774        }
17775    }
17776
17777    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17778        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17779            ProcessRecord r = mLruProcesses.get(i);
17780            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17781                try {
17782                    r.thread.dispatchPackageBroadcast(cmd, packages);
17783                } catch (RemoteException ex) {
17784                }
17785            }
17786        }
17787    }
17788
17789    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17790            int callingUid, int[] users) {
17791        // TODO: come back and remove this assumption to triage all broadcasts
17792        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17793
17794        List<ResolveInfo> receivers = null;
17795        try {
17796            HashSet<ComponentName> singleUserReceivers = null;
17797            boolean scannedFirstReceivers = false;
17798            for (int user : users) {
17799                // Skip users that have Shell restrictions, with exception of always permitted
17800                // Shell broadcasts
17801                if (callingUid == Process.SHELL_UID
17802                        && mUserController.hasUserRestriction(
17803                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17804                        && !isPermittedShellBroadcast(intent)) {
17805                    continue;
17806                }
17807                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17808                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17809                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17810                    // If this is not the system user, we need to check for
17811                    // any receivers that should be filtered out.
17812                    for (int i=0; i<newReceivers.size(); i++) {
17813                        ResolveInfo ri = newReceivers.get(i);
17814                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17815                            newReceivers.remove(i);
17816                            i--;
17817                        }
17818                    }
17819                }
17820                if (newReceivers != null && newReceivers.size() == 0) {
17821                    newReceivers = null;
17822                }
17823                if (receivers == null) {
17824                    receivers = newReceivers;
17825                } else if (newReceivers != null) {
17826                    // We need to concatenate the additional receivers
17827                    // found with what we have do far.  This would be easy,
17828                    // but we also need to de-dup any receivers that are
17829                    // singleUser.
17830                    if (!scannedFirstReceivers) {
17831                        // Collect any single user receivers we had already retrieved.
17832                        scannedFirstReceivers = true;
17833                        for (int i=0; i<receivers.size(); i++) {
17834                            ResolveInfo ri = receivers.get(i);
17835                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17836                                ComponentName cn = new ComponentName(
17837                                        ri.activityInfo.packageName, ri.activityInfo.name);
17838                                if (singleUserReceivers == null) {
17839                                    singleUserReceivers = new HashSet<ComponentName>();
17840                                }
17841                                singleUserReceivers.add(cn);
17842                            }
17843                        }
17844                    }
17845                    // Add the new results to the existing results, tracking
17846                    // and de-dupping single user receivers.
17847                    for (int i=0; i<newReceivers.size(); i++) {
17848                        ResolveInfo ri = newReceivers.get(i);
17849                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17850                            ComponentName cn = new ComponentName(
17851                                    ri.activityInfo.packageName, ri.activityInfo.name);
17852                            if (singleUserReceivers == null) {
17853                                singleUserReceivers = new HashSet<ComponentName>();
17854                            }
17855                            if (!singleUserReceivers.contains(cn)) {
17856                                singleUserReceivers.add(cn);
17857                                receivers.add(ri);
17858                            }
17859                        } else {
17860                            receivers.add(ri);
17861                        }
17862                    }
17863                }
17864            }
17865        } catch (RemoteException ex) {
17866            // pm is in same process, this will never happen.
17867        }
17868        return receivers;
17869    }
17870
17871    private boolean isPermittedShellBroadcast(Intent intent) {
17872        // remote bugreport should always be allowed to be taken
17873        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17874    }
17875
17876    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17877            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17878        final String action = intent.getAction();
17879        if (isProtectedBroadcast
17880                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17881                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17882                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17883                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17884                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17885                || Intent.ACTION_MASTER_CLEAR.equals(action)
17886                || Intent.ACTION_FACTORY_RESET.equals(action)
17887                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17888                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17889                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17890                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17891                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17892            // Broadcast is either protected, or it's a public action that
17893            // we've relaxed, so it's fine for system internals to send.
17894            return;
17895        }
17896
17897        // This broadcast may be a problem...  but there are often system components that
17898        // want to send an internal broadcast to themselves, which is annoying to have to
17899        // explicitly list each action as a protected broadcast, so we will check for that
17900        // one safe case and allow it: an explicit broadcast, only being received by something
17901        // that has protected itself.
17902        if (receivers != null && receivers.size() > 0
17903                && (intent.getPackage() != null || intent.getComponent() != null)) {
17904            boolean allProtected = true;
17905            for (int i = receivers.size()-1; i >= 0; i--) {
17906                Object target = receivers.get(i);
17907                if (target instanceof ResolveInfo) {
17908                    ResolveInfo ri = (ResolveInfo)target;
17909                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17910                        allProtected = false;
17911                        break;
17912                    }
17913                } else {
17914                    BroadcastFilter bf = (BroadcastFilter)target;
17915                    if (bf.requiredPermission == null) {
17916                        allProtected = false;
17917                        break;
17918                    }
17919                }
17920            }
17921            if (allProtected) {
17922                // All safe!
17923                return;
17924            }
17925        }
17926
17927        // The vast majority of broadcasts sent from system internals
17928        // should be protected to avoid security holes, so yell loudly
17929        // to ensure we examine these cases.
17930        if (callerApp != null) {
17931            Log.wtf(TAG, "Sending non-protected broadcast " + action
17932                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17933                    new Throwable());
17934        } else {
17935            Log.wtf(TAG, "Sending non-protected broadcast " + action
17936                            + " from system uid " + UserHandle.formatUid(callingUid)
17937                            + " pkg " + callerPackage,
17938                    new Throwable());
17939        }
17940    }
17941
17942    final int broadcastIntentLocked(ProcessRecord callerApp,
17943            String callerPackage, Intent intent, String resolvedType,
17944            IIntentReceiver resultTo, int resultCode, String resultData,
17945            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17946            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17947        intent = new Intent(intent);
17948
17949        // By default broadcasts do not go to stopped apps.
17950        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17951
17952        // If we have not finished booting, don't allow this to launch new processes.
17953        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17954            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17955        }
17956
17957        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17958                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17959                + " ordered=" + ordered + " userid=" + userId);
17960        if ((resultTo != null) && !ordered) {
17961            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17962        }
17963
17964        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17965                ALLOW_NON_FULL, "broadcast", callerPackage);
17966
17967        // Make sure that the user who is receiving this broadcast is running.
17968        // If not, we will just skip it. Make an exception for shutdown broadcasts
17969        // and upgrade steps.
17970
17971        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17972            if ((callingUid != Process.SYSTEM_UID
17973                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17974                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17975                Slog.w(TAG, "Skipping broadcast of " + intent
17976                        + ": user " + userId + " is stopped");
17977                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17978            }
17979        }
17980
17981        BroadcastOptions brOptions = null;
17982        if (bOptions != null) {
17983            brOptions = new BroadcastOptions(bOptions);
17984            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17985                // See if the caller is allowed to do this.  Note we are checking against
17986                // the actual real caller (not whoever provided the operation as say a
17987                // PendingIntent), because that who is actually supplied the arguments.
17988                if (checkComponentPermission(
17989                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17990                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17991                        != PackageManager.PERMISSION_GRANTED) {
17992                    String msg = "Permission Denial: " + intent.getAction()
17993                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17994                            + ", uid=" + callingUid + ")"
17995                            + " requires "
17996                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17997                    Slog.w(TAG, msg);
17998                    throw new SecurityException(msg);
17999                }
18000            }
18001        }
18002
18003        // Verify that protected broadcasts are only being sent by system code,
18004        // and that system code is only sending protected broadcasts.
18005        final String action = intent.getAction();
18006        final boolean isProtectedBroadcast;
18007        try {
18008            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18009        } catch (RemoteException e) {
18010            Slog.w(TAG, "Remote exception", e);
18011            return ActivityManager.BROADCAST_SUCCESS;
18012        }
18013
18014        final boolean isCallerSystem;
18015        switch (UserHandle.getAppId(callingUid)) {
18016            case Process.ROOT_UID:
18017            case Process.SYSTEM_UID:
18018            case Process.PHONE_UID:
18019            case Process.BLUETOOTH_UID:
18020            case Process.NFC_UID:
18021                if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18022                    isCallerSystem = false;
18023                } else {
18024                    isCallerSystem = true;
18025                }
18026                break;
18027            default:
18028                isCallerSystem = (callerApp != null) && callerApp.persistent;
18029                break;
18030        }
18031
18032        // First line security check before anything else: stop non-system apps from
18033        // sending protected broadcasts.
18034        if (!isCallerSystem) {
18035            if (isProtectedBroadcast) {
18036                String msg = "Permission Denial: not allowed to send broadcast "
18037                        + action + " from pid="
18038                        + callingPid + ", uid=" + callingUid;
18039                Slog.w(TAG, msg);
18040                throw new SecurityException(msg);
18041
18042            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18043                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18044                // Special case for compatibility: we don't want apps to send this,
18045                // but historically it has not been protected and apps may be using it
18046                // to poke their own app widget.  So, instead of making it protected,
18047                // just limit it to the caller.
18048                if (callerPackage == null) {
18049                    String msg = "Permission Denial: not allowed to send broadcast "
18050                            + action + " from unknown caller.";
18051                    Slog.w(TAG, msg);
18052                    throw new SecurityException(msg);
18053                } else if (intent.getComponent() != null) {
18054                    // They are good enough to send to an explicit component...  verify
18055                    // it is being sent to the calling app.
18056                    if (!intent.getComponent().getPackageName().equals(
18057                            callerPackage)) {
18058                        String msg = "Permission Denial: not allowed to send broadcast "
18059                                + action + " to "
18060                                + intent.getComponent().getPackageName() + " from "
18061                                + callerPackage;
18062                        Slog.w(TAG, msg);
18063                        throw new SecurityException(msg);
18064                    }
18065                } else {
18066                    // Limit broadcast to their own package.
18067                    intent.setPackage(callerPackage);
18068                }
18069            }
18070        }
18071
18072        if (action != null) {
18073            switch (action) {
18074                case Intent.ACTION_UID_REMOVED:
18075                case Intent.ACTION_PACKAGE_REMOVED:
18076                case Intent.ACTION_PACKAGE_CHANGED:
18077                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18078                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18079                case Intent.ACTION_PACKAGES_SUSPENDED:
18080                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18081                    // Handle special intents: if this broadcast is from the package
18082                    // manager about a package being removed, we need to remove all of
18083                    // its activities from the history stack.
18084                    if (checkComponentPermission(
18085                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18086                            callingPid, callingUid, -1, true)
18087                            != PackageManager.PERMISSION_GRANTED) {
18088                        String msg = "Permission Denial: " + intent.getAction()
18089                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18090                                + ", uid=" + callingUid + ")"
18091                                + " requires "
18092                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18093                        Slog.w(TAG, msg);
18094                        throw new SecurityException(msg);
18095                    }
18096                    switch (action) {
18097                        case Intent.ACTION_UID_REMOVED:
18098                            final Bundle intentExtras = intent.getExtras();
18099                            final int uid = intentExtras != null
18100                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18101                            if (uid >= 0) {
18102                                mBatteryStatsService.removeUid(uid);
18103                                mAppOpsService.uidRemoved(uid);
18104                            }
18105                            break;
18106                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18107                            // If resources are unavailable just force stop all those packages
18108                            // and flush the attribute cache as well.
18109                            String list[] =
18110                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18111                            if (list != null && list.length > 0) {
18112                                for (int i = 0; i < list.length; i++) {
18113                                    forceStopPackageLocked(list[i], -1, false, true, true,
18114                                            false, false, userId, "storage unmount");
18115                                }
18116                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18117                                sendPackageBroadcastLocked(
18118                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18119                                        list, userId);
18120                            }
18121                            break;
18122                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18123                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18124                            break;
18125                        case Intent.ACTION_PACKAGE_REMOVED:
18126                        case Intent.ACTION_PACKAGE_CHANGED:
18127                            Uri data = intent.getData();
18128                            String ssp;
18129                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18130                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18131                                final boolean replacing =
18132                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18133                                final boolean killProcess =
18134                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18135                                final boolean fullUninstall = removed && !replacing;
18136                                if (removed) {
18137                                    if (killProcess) {
18138                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18139                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18140                                                false, true, true, false, fullUninstall, userId,
18141                                                removed ? "pkg removed" : "pkg changed");
18142                                    }
18143                                    final int cmd = killProcess
18144                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18145                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18146                                    sendPackageBroadcastLocked(cmd,
18147                                            new String[] {ssp}, userId);
18148                                    if (fullUninstall) {
18149                                        mAppOpsService.packageRemoved(
18150                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18151
18152                                        // Remove all permissions granted from/to this package
18153                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18154
18155                                        removeTasksByPackageNameLocked(ssp, userId);
18156
18157                                        // Hide the "unsupported display" dialog if necessary.
18158                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18159                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18160                                            mUnsupportedDisplaySizeDialog.dismiss();
18161                                            mUnsupportedDisplaySizeDialog = null;
18162                                        }
18163                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18164                                        mBatteryStatsService.notePackageUninstalled(ssp);
18165                                    }
18166                                } else {
18167                                    if (killProcess) {
18168                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18169                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18170                                                userId, ProcessList.INVALID_ADJ,
18171                                                false, true, true, false, "change " + ssp);
18172                                    }
18173                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18174                                            intent.getStringArrayExtra(
18175                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18176                                }
18177                            }
18178                            break;
18179                        case Intent.ACTION_PACKAGES_SUSPENDED:
18180                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18181                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18182                                    intent.getAction());
18183                            final String[] packageNames = intent.getStringArrayExtra(
18184                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18185                            final int userHandle = intent.getIntExtra(
18186                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18187
18188                            synchronized(ActivityManagerService.this) {
18189                                mRecentTasks.onPackagesSuspendedChanged(
18190                                        packageNames, suspended, userHandle);
18191                            }
18192                            break;
18193                    }
18194                    break;
18195                case Intent.ACTION_PACKAGE_REPLACED:
18196                {
18197                    final Uri data = intent.getData();
18198                    final String ssp;
18199                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18200                        final ApplicationInfo aInfo =
18201                                getPackageManagerInternalLocked().getApplicationInfo(
18202                                        ssp,
18203                                        userId);
18204                        if (aInfo == null) {
18205                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18206                                    + " ssp=" + ssp + " data=" + data);
18207                            return ActivityManager.BROADCAST_SUCCESS;
18208                        }
18209                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18210                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18211                                new String[] {ssp}, userId);
18212                    }
18213                    break;
18214                }
18215                case Intent.ACTION_PACKAGE_ADDED:
18216                {
18217                    // Special case for adding a package: by default turn on compatibility mode.
18218                    Uri data = intent.getData();
18219                    String ssp;
18220                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18221                        final boolean replacing =
18222                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18223                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18224
18225                        try {
18226                            ApplicationInfo ai = AppGlobals.getPackageManager().
18227                                    getApplicationInfo(ssp, 0, 0);
18228                            mBatteryStatsService.notePackageInstalled(ssp,
18229                                    ai != null ? ai.versionCode : 0);
18230                        } catch (RemoteException e) {
18231                        }
18232                    }
18233                    break;
18234                }
18235                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18236                {
18237                    Uri data = intent.getData();
18238                    String ssp;
18239                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18240                        // Hide the "unsupported display" dialog if necessary.
18241                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18242                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18243                            mUnsupportedDisplaySizeDialog.dismiss();
18244                            mUnsupportedDisplaySizeDialog = null;
18245                        }
18246                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18247                    }
18248                    break;
18249                }
18250                case Intent.ACTION_TIMEZONE_CHANGED:
18251                    // If this is the time zone changed action, queue up a message that will reset
18252                    // the timezone of all currently running processes. This message will get
18253                    // queued up before the broadcast happens.
18254                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18255                    break;
18256                case Intent.ACTION_TIME_CHANGED:
18257                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18258                    // the tri-state value it may contain and "unknown".
18259                    // For convenience we re-use the Intent extra values.
18260                    final int NO_EXTRA_VALUE_FOUND = -1;
18261                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18262                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18263                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18264                    // Only send a message if the time preference is available.
18265                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18266                        Message updateTimePreferenceMsg =
18267                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18268                                        timeFormatPreferenceMsgValue, 0);
18269                        mHandler.sendMessage(updateTimePreferenceMsg);
18270                    }
18271                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18272                    synchronized (stats) {
18273                        stats.noteCurrentTimeChangedLocked();
18274                    }
18275                    break;
18276                case Intent.ACTION_CLEAR_DNS_CACHE:
18277                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18278                    break;
18279                case Proxy.PROXY_CHANGE_ACTION:
18280                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18281                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18282                    break;
18283                case android.hardware.Camera.ACTION_NEW_PICTURE:
18284                case android.hardware.Camera.ACTION_NEW_VIDEO:
18285                    // These broadcasts are no longer allowed by the system, since they can
18286                    // cause significant thrashing at a crictical point (using the camera).
18287                    // Apps should use JobScehduler to monitor for media provider changes.
18288                    Slog.w(TAG, action + " no longer allowed; dropping from "
18289                            + UserHandle.formatUid(callingUid));
18290                    if (resultTo != null) {
18291                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18292                        try {
18293                            queue.performReceiveLocked(callerApp, resultTo, intent,
18294                                    Activity.RESULT_CANCELED, null, null,
18295                                    false, false, userId);
18296                        } catch (RemoteException e) {
18297                            Slog.w(TAG, "Failure ["
18298                                    + queue.mQueueName + "] sending broadcast result of "
18299                                    + intent, e);
18300
18301                        }
18302                    }
18303                    // Lie; we don't want to crash the app.
18304                    return ActivityManager.BROADCAST_SUCCESS;
18305                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18306                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18307                    break;
18308            }
18309        }
18310
18311        // Add to the sticky list if requested.
18312        if (sticky) {
18313            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18314                    callingPid, callingUid)
18315                    != PackageManager.PERMISSION_GRANTED) {
18316                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18317                        + callingPid + ", uid=" + callingUid
18318                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18319                Slog.w(TAG, msg);
18320                throw new SecurityException(msg);
18321            }
18322            if (requiredPermissions != null && requiredPermissions.length > 0) {
18323                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18324                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18325                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18326            }
18327            if (intent.getComponent() != null) {
18328                throw new SecurityException(
18329                        "Sticky broadcasts can't target a specific component");
18330            }
18331            // We use userId directly here, since the "all" target is maintained
18332            // as a separate set of sticky broadcasts.
18333            if (userId != UserHandle.USER_ALL) {
18334                // But first, if this is not a broadcast to all users, then
18335                // make sure it doesn't conflict with an existing broadcast to
18336                // all users.
18337                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18338                        UserHandle.USER_ALL);
18339                if (stickies != null) {
18340                    ArrayList<Intent> list = stickies.get(intent.getAction());
18341                    if (list != null) {
18342                        int N = list.size();
18343                        int i;
18344                        for (i=0; i<N; i++) {
18345                            if (intent.filterEquals(list.get(i))) {
18346                                throw new IllegalArgumentException(
18347                                        "Sticky broadcast " + intent + " for user "
18348                                        + userId + " conflicts with existing global broadcast");
18349                            }
18350                        }
18351                    }
18352                }
18353            }
18354            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18355            if (stickies == null) {
18356                stickies = new ArrayMap<>();
18357                mStickyBroadcasts.put(userId, stickies);
18358            }
18359            ArrayList<Intent> list = stickies.get(intent.getAction());
18360            if (list == null) {
18361                list = new ArrayList<>();
18362                stickies.put(intent.getAction(), list);
18363            }
18364            final int stickiesCount = list.size();
18365            int i;
18366            for (i = 0; i < stickiesCount; i++) {
18367                if (intent.filterEquals(list.get(i))) {
18368                    // This sticky already exists, replace it.
18369                    list.set(i, new Intent(intent));
18370                    break;
18371                }
18372            }
18373            if (i >= stickiesCount) {
18374                list.add(new Intent(intent));
18375            }
18376        }
18377
18378        int[] users;
18379        if (userId == UserHandle.USER_ALL) {
18380            // Caller wants broadcast to go to all started users.
18381            users = mUserController.getStartedUserArrayLocked();
18382        } else {
18383            // Caller wants broadcast to go to one specific user.
18384            users = new int[] {userId};
18385        }
18386
18387        // Figure out who all will receive this broadcast.
18388        List receivers = null;
18389        List<BroadcastFilter> registeredReceivers = null;
18390        // Need to resolve the intent to interested receivers...
18391        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18392                 == 0) {
18393            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18394        }
18395        if (intent.getComponent() == null) {
18396            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18397                // Query one target user at a time, excluding shell-restricted users
18398                for (int i = 0; i < users.length; i++) {
18399                    if (mUserController.hasUserRestriction(
18400                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18401                        continue;
18402                    }
18403                    List<BroadcastFilter> registeredReceiversForUser =
18404                            mReceiverResolver.queryIntent(intent,
18405                                    resolvedType, false, false /*visibleToEphemeral*/,
18406                                    false /*isEphemeral*/, users[i]);
18407                    if (registeredReceivers == null) {
18408                        registeredReceivers = registeredReceiversForUser;
18409                    } else if (registeredReceiversForUser != null) {
18410                        registeredReceivers.addAll(registeredReceiversForUser);
18411                    }
18412                }
18413            } else {
18414                registeredReceivers = mReceiverResolver.queryIntent(intent,
18415                        resolvedType, false, false /*visibleToEphemeral*/,
18416                        false /*isEphemeral*/, userId);
18417            }
18418        }
18419
18420        final boolean replacePending =
18421                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18422
18423        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18424                + " replacePending=" + replacePending);
18425
18426        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18427        if (!ordered && NR > 0) {
18428            // If we are not serializing this broadcast, then send the
18429            // registered receivers separately so they don't wait for the
18430            // components to be launched.
18431            if (isCallerSystem) {
18432                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18433                        isProtectedBroadcast, registeredReceivers);
18434            }
18435            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18436            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18437                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18438                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18439                    resultExtras, ordered, sticky, false, userId);
18440            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18441            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18442            if (!replaced) {
18443                queue.enqueueParallelBroadcastLocked(r);
18444                queue.scheduleBroadcastsLocked();
18445            }
18446            registeredReceivers = null;
18447            NR = 0;
18448        }
18449
18450        // Merge into one list.
18451        int ir = 0;
18452        if (receivers != null) {
18453            // A special case for PACKAGE_ADDED: do not allow the package
18454            // being added to see this broadcast.  This prevents them from
18455            // using this as a back door to get run as soon as they are
18456            // installed.  Maybe in the future we want to have a special install
18457            // broadcast or such for apps, but we'd like to deliberately make
18458            // this decision.
18459            String skipPackages[] = null;
18460            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18461                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18462                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18463                Uri data = intent.getData();
18464                if (data != null) {
18465                    String pkgName = data.getSchemeSpecificPart();
18466                    if (pkgName != null) {
18467                        skipPackages = new String[] { pkgName };
18468                    }
18469                }
18470            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18471                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18472            }
18473            if (skipPackages != null && (skipPackages.length > 0)) {
18474                for (String skipPackage : skipPackages) {
18475                    if (skipPackage != null) {
18476                        int NT = receivers.size();
18477                        for (int it=0; it<NT; it++) {
18478                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18479                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18480                                receivers.remove(it);
18481                                it--;
18482                                NT--;
18483                            }
18484                        }
18485                    }
18486                }
18487            }
18488
18489            int NT = receivers != null ? receivers.size() : 0;
18490            int it = 0;
18491            ResolveInfo curt = null;
18492            BroadcastFilter curr = null;
18493            while (it < NT && ir < NR) {
18494                if (curt == null) {
18495                    curt = (ResolveInfo)receivers.get(it);
18496                }
18497                if (curr == null) {
18498                    curr = registeredReceivers.get(ir);
18499                }
18500                if (curr.getPriority() >= curt.priority) {
18501                    // Insert this broadcast record into the final list.
18502                    receivers.add(it, curr);
18503                    ir++;
18504                    curr = null;
18505                    it++;
18506                    NT++;
18507                } else {
18508                    // Skip to the next ResolveInfo in the final list.
18509                    it++;
18510                    curt = null;
18511                }
18512            }
18513        }
18514        while (ir < NR) {
18515            if (receivers == null) {
18516                receivers = new ArrayList();
18517            }
18518            receivers.add(registeredReceivers.get(ir));
18519            ir++;
18520        }
18521
18522        if (isCallerSystem) {
18523            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18524                    isProtectedBroadcast, receivers);
18525        }
18526
18527        if ((receivers != null && receivers.size() > 0)
18528                || resultTo != null) {
18529            BroadcastQueue queue = broadcastQueueForIntent(intent);
18530            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18531                    callerPackage, callingPid, callingUid, resolvedType,
18532                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18533                    resultData, resultExtras, ordered, sticky, false, userId);
18534
18535            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18536                    + ": prev had " + queue.mOrderedBroadcasts.size());
18537            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18538                    "Enqueueing broadcast " + r.intent.getAction());
18539
18540            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18541            if (!replaced) {
18542                queue.enqueueOrderedBroadcastLocked(r);
18543                queue.scheduleBroadcastsLocked();
18544            }
18545        } else {
18546            // There was nobody interested in the broadcast, but we still want to record
18547            // that it happened.
18548            if (intent.getComponent() == null && intent.getPackage() == null
18549                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18550                // This was an implicit broadcast... let's record it for posterity.
18551                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18552            }
18553        }
18554
18555        return ActivityManager.BROADCAST_SUCCESS;
18556    }
18557
18558    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18559            int skipCount, long dispatchTime) {
18560        final long now = SystemClock.elapsedRealtime();
18561        if (mCurBroadcastStats == null ||
18562                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18563            mLastBroadcastStats = mCurBroadcastStats;
18564            if (mLastBroadcastStats != null) {
18565                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18566                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18567            }
18568            mCurBroadcastStats = new BroadcastStats();
18569        }
18570        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18571    }
18572
18573    final Intent verifyBroadcastLocked(Intent intent) {
18574        // Refuse possible leaked file descriptors
18575        if (intent != null && intent.hasFileDescriptors() == true) {
18576            throw new IllegalArgumentException("File descriptors passed in Intent");
18577        }
18578
18579        int flags = intent.getFlags();
18580
18581        if (!mProcessesReady) {
18582            // if the caller really truly claims to know what they're doing, go
18583            // ahead and allow the broadcast without launching any receivers
18584            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18585                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18586            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18587                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18588                        + " before boot completion");
18589                throw new IllegalStateException("Cannot broadcast before boot completed");
18590            }
18591        }
18592
18593        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18594            throw new IllegalArgumentException(
18595                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18596        }
18597
18598        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18599            switch (Binder.getCallingUid()) {
18600                case Process.ROOT_UID:
18601                case Process.SHELL_UID:
18602                    break;
18603                default:
18604                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
18605                            + Binder.getCallingUid());
18606                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
18607                    break;
18608            }
18609        }
18610
18611        return intent;
18612    }
18613
18614    public final int broadcastIntent(IApplicationThread caller,
18615            Intent intent, String resolvedType, IIntentReceiver resultTo,
18616            int resultCode, String resultData, Bundle resultExtras,
18617            String[] requiredPermissions, int appOp, Bundle bOptions,
18618            boolean serialized, boolean sticky, int userId) {
18619        enforceNotIsolatedCaller("broadcastIntent");
18620        synchronized(this) {
18621            intent = verifyBroadcastLocked(intent);
18622
18623            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18624            final int callingPid = Binder.getCallingPid();
18625            final int callingUid = Binder.getCallingUid();
18626            final long origId = Binder.clearCallingIdentity();
18627            int res = broadcastIntentLocked(callerApp,
18628                    callerApp != null ? callerApp.info.packageName : null,
18629                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18630                    requiredPermissions, appOp, bOptions, serialized, sticky,
18631                    callingPid, callingUid, userId);
18632            Binder.restoreCallingIdentity(origId);
18633            return res;
18634        }
18635    }
18636
18637
18638    int broadcastIntentInPackage(String packageName, int uid,
18639            Intent intent, String resolvedType, IIntentReceiver resultTo,
18640            int resultCode, String resultData, Bundle resultExtras,
18641            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18642            int userId) {
18643        synchronized(this) {
18644            intent = verifyBroadcastLocked(intent);
18645
18646            final long origId = Binder.clearCallingIdentity();
18647            String[] requiredPermissions = requiredPermission == null ? null
18648                    : new String[] {requiredPermission};
18649            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18650                    resultTo, resultCode, resultData, resultExtras,
18651                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18652                    sticky, -1, uid, userId);
18653            Binder.restoreCallingIdentity(origId);
18654            return res;
18655        }
18656    }
18657
18658    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18659        // Refuse possible leaked file descriptors
18660        if (intent != null && intent.hasFileDescriptors() == true) {
18661            throw new IllegalArgumentException("File descriptors passed in Intent");
18662        }
18663
18664        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18665                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18666
18667        synchronized(this) {
18668            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18669                    != PackageManager.PERMISSION_GRANTED) {
18670                String msg = "Permission Denial: unbroadcastIntent() from pid="
18671                        + Binder.getCallingPid()
18672                        + ", uid=" + Binder.getCallingUid()
18673                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18674                Slog.w(TAG, msg);
18675                throw new SecurityException(msg);
18676            }
18677            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18678            if (stickies != null) {
18679                ArrayList<Intent> list = stickies.get(intent.getAction());
18680                if (list != null) {
18681                    int N = list.size();
18682                    int i;
18683                    for (i=0; i<N; i++) {
18684                        if (intent.filterEquals(list.get(i))) {
18685                            list.remove(i);
18686                            break;
18687                        }
18688                    }
18689                    if (list.size() <= 0) {
18690                        stickies.remove(intent.getAction());
18691                    }
18692                }
18693                if (stickies.size() <= 0) {
18694                    mStickyBroadcasts.remove(userId);
18695                }
18696            }
18697        }
18698    }
18699
18700    void backgroundServicesFinishedLocked(int userId) {
18701        for (BroadcastQueue queue : mBroadcastQueues) {
18702            queue.backgroundServicesFinishedLocked(userId);
18703        }
18704    }
18705
18706    public void finishReceiver(IBinder who, int resultCode, String resultData,
18707            Bundle resultExtras, boolean resultAbort, int flags) {
18708        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18709
18710        // Refuse possible leaked file descriptors
18711        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18712            throw new IllegalArgumentException("File descriptors passed in Bundle");
18713        }
18714
18715        final long origId = Binder.clearCallingIdentity();
18716        try {
18717            boolean doNext = false;
18718            BroadcastRecord r;
18719
18720            synchronized(this) {
18721                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18722                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18723                r = queue.getMatchingOrderedReceiver(who);
18724                if (r != null) {
18725                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18726                        resultData, resultExtras, resultAbort, true);
18727                }
18728            }
18729
18730            if (doNext) {
18731                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
18732                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
18733                      String.format("ProcessBroadcast from %s (%s) %s", r.callerPackage,
18734                        r.callerApp == null ? "caller unknown" : r.callerApp.toShortString(),
18735                        r.intent == null ? "" : r.intent.toString()));
18736                }
18737                r.queue.processNextBroadcast(false);
18738                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
18739            }
18740            trimApplications();
18741        } finally {
18742            Binder.restoreCallingIdentity(origId);
18743        }
18744    }
18745
18746    // =========================================================
18747    // INSTRUMENTATION
18748    // =========================================================
18749
18750    public boolean startInstrumentation(ComponentName className,
18751            String profileFile, int flags, Bundle arguments,
18752            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18753            int userId, String abiOverride) {
18754        enforceNotIsolatedCaller("startInstrumentation");
18755        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18756                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18757        // Refuse possible leaked file descriptors
18758        if (arguments != null && arguments.hasFileDescriptors()) {
18759            throw new IllegalArgumentException("File descriptors passed in Bundle");
18760        }
18761
18762        synchronized(this) {
18763            InstrumentationInfo ii = null;
18764            ApplicationInfo ai = null;
18765            try {
18766                ii = mContext.getPackageManager().getInstrumentationInfo(
18767                    className, STOCK_PM_FLAGS);
18768                ai = AppGlobals.getPackageManager().getApplicationInfo(
18769                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18770            } catch (PackageManager.NameNotFoundException e) {
18771            } catch (RemoteException e) {
18772            }
18773            if (ii == null) {
18774                reportStartInstrumentationFailureLocked(watcher, className,
18775                        "Unable to find instrumentation info for: " + className);
18776                return false;
18777            }
18778            if (ai == null) {
18779                reportStartInstrumentationFailureLocked(watcher, className,
18780                        "Unable to find instrumentation target package: " + ii.targetPackage);
18781                return false;
18782            }
18783            if (!ai.hasCode()) {
18784                reportStartInstrumentationFailureLocked(watcher, className,
18785                        "Instrumentation target has no code: " + ii.targetPackage);
18786                return false;
18787            }
18788
18789            int match = mContext.getPackageManager().checkSignatures(
18790                    ii.targetPackage, ii.packageName);
18791            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18792                String msg = "Permission Denial: starting instrumentation "
18793                        + className + " from pid="
18794                        + Binder.getCallingPid()
18795                        + ", uid=" + Binder.getCallingPid()
18796                        + " not allowed because package " + ii.packageName
18797                        + " does not have a signature matching the target "
18798                        + ii.targetPackage;
18799                reportStartInstrumentationFailureLocked(watcher, className, msg);
18800                throw new SecurityException(msg);
18801            }
18802
18803            final long origId = Binder.clearCallingIdentity();
18804            // Instrumentation can kill and relaunch even persistent processes
18805            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18806                    "start instr");
18807            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18808            app.instrumentationClass = className;
18809            app.instrumentationInfo = ai;
18810            app.instrumentationProfileFile = profileFile;
18811            app.instrumentationArguments = arguments;
18812            app.instrumentationWatcher = watcher;
18813            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18814            app.instrumentationResultClass = className;
18815            Binder.restoreCallingIdentity(origId);
18816        }
18817
18818        return true;
18819    }
18820
18821    /**
18822     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18823     * error to the logs, but if somebody is watching, send the report there too.  This enables
18824     * the "am" command to report errors with more information.
18825     *
18826     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18827     * @param cn The component name of the instrumentation.
18828     * @param report The error report.
18829     */
18830    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18831            ComponentName cn, String report) {
18832        Slog.w(TAG, report);
18833        if (watcher != null) {
18834            Bundle results = new Bundle();
18835            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18836            results.putString("Error", report);
18837            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18838        }
18839    }
18840
18841    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18842        if (app.instrumentationWatcher != null) {
18843            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18844                    app.instrumentationClass, resultCode, results);
18845        }
18846
18847        // Can't call out of the system process with a lock held, so post a message.
18848        if (app.instrumentationUiAutomationConnection != null) {
18849            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18850                    app.instrumentationUiAutomationConnection).sendToTarget();
18851        }
18852
18853        app.instrumentationWatcher = null;
18854        app.instrumentationUiAutomationConnection = null;
18855        app.instrumentationClass = null;
18856        app.instrumentationInfo = null;
18857        app.instrumentationProfileFile = null;
18858        app.instrumentationArguments = null;
18859
18860        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18861                "finished inst");
18862    }
18863
18864    public void finishInstrumentation(IApplicationThread target,
18865            int resultCode, Bundle results) {
18866        int userId = UserHandle.getCallingUserId();
18867        // Refuse possible leaked file descriptors
18868        if (results != null && results.hasFileDescriptors()) {
18869            throw new IllegalArgumentException("File descriptors passed in Intent");
18870        }
18871
18872        synchronized(this) {
18873            ProcessRecord app = getRecordForAppLocked(target);
18874            if (app == null) {
18875                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18876                return;
18877            }
18878            final long origId = Binder.clearCallingIdentity();
18879            finishInstrumentationLocked(app, resultCode, results);
18880            Binder.restoreCallingIdentity(origId);
18881        }
18882    }
18883
18884    // =========================================================
18885    // CONFIGURATION
18886    // =========================================================
18887
18888    public ConfigurationInfo getDeviceConfigurationInfo() {
18889        ConfigurationInfo config = new ConfigurationInfo();
18890        synchronized (this) {
18891            final Configuration globalConfig = getGlobalConfiguration();
18892            config.reqTouchScreen = globalConfig.touchscreen;
18893            config.reqKeyboardType = globalConfig.keyboard;
18894            config.reqNavigation = globalConfig.navigation;
18895            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18896                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18897                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18898            }
18899            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18900                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18901                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18902            }
18903            config.reqGlEsVersion = GL_ES_VERSION;
18904        }
18905        return config;
18906    }
18907
18908    ActivityStack getFocusedStack() {
18909        return mStackSupervisor.getFocusedStack();
18910    }
18911
18912    @Override
18913    public int getFocusedStackId() throws RemoteException {
18914        ActivityStack focusedStack = getFocusedStack();
18915        if (focusedStack != null) {
18916            return focusedStack.getStackId();
18917        }
18918        return -1;
18919    }
18920
18921    public Configuration getConfiguration() {
18922        Configuration ci;
18923        synchronized(this) {
18924            ci = new Configuration(getGlobalConfiguration());
18925            ci.userSetLocale = false;
18926        }
18927        return ci;
18928    }
18929
18930    @Override
18931    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18932        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18933        synchronized (this) {
18934            mSuppressResizeConfigChanges = suppress;
18935        }
18936    }
18937
18938    @Override
18939    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18940        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18941        if (StackId.isHomeOrRecentsStack(fromStackId)) {
18942            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
18943        }
18944        synchronized (this) {
18945            final long origId = Binder.clearCallingIdentity();
18946            try {
18947                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18948            } finally {
18949                Binder.restoreCallingIdentity(origId);
18950            }
18951        }
18952    }
18953
18954    @Override
18955    public void updatePersistentConfiguration(Configuration values) {
18956        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
18957        enforceWriteSettingsPermission("updatePersistentConfiguration()");
18958        if (values == null) {
18959            throw new NullPointerException("Configuration must not be null");
18960        }
18961
18962        int userId = UserHandle.getCallingUserId();
18963
18964        synchronized(this) {
18965            updatePersistentConfigurationLocked(values, userId);
18966        }
18967    }
18968
18969    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18970        final long origId = Binder.clearCallingIdentity();
18971        try {
18972            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18973        } finally {
18974            Binder.restoreCallingIdentity(origId);
18975        }
18976    }
18977
18978    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18979        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18980                FONT_SCALE, 1.0f, userId);
18981
18982        synchronized (this) {
18983            if (getGlobalConfiguration().fontScale == scaleFactor) {
18984                return;
18985            }
18986
18987            final Configuration configuration
18988                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18989            configuration.fontScale = scaleFactor;
18990            updatePersistentConfigurationLocked(configuration, userId);
18991        }
18992    }
18993
18994    private void enforceWriteSettingsPermission(String func) {
18995        int uid = Binder.getCallingUid();
18996        if (uid == Process.ROOT_UID) {
18997            return;
18998        }
18999
19000        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19001                Settings.getPackageNameForUid(mContext, uid), false)) {
19002            return;
19003        }
19004
19005        String msg = "Permission Denial: " + func + " from pid="
19006                + Binder.getCallingPid()
19007                + ", uid=" + uid
19008                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19009        Slog.w(TAG, msg);
19010        throw new SecurityException(msg);
19011    }
19012
19013    @Override
19014    public boolean updateConfiguration(Configuration values) {
19015        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19016
19017        synchronized(this) {
19018            if (values == null && mWindowManager != null) {
19019                // sentinel: fetch the current configuration from the window manager
19020                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19021            }
19022
19023            if (mWindowManager != null) {
19024                // Update OOM levels based on display size.
19025                mProcessList.applyDisplaySize(mWindowManager);
19026            }
19027
19028            final long origId = Binder.clearCallingIdentity();
19029            try {
19030                if (values != null) {
19031                    Settings.System.clearConfiguration(values);
19032                }
19033                updateConfigurationLocked(values, null, false, false /* persistent */,
19034                        UserHandle.USER_NULL, false /* deferResume */,
19035                        mTmpUpdateConfigurationResult);
19036                return mTmpUpdateConfigurationResult.changes != 0;
19037            } finally {
19038                Binder.restoreCallingIdentity(origId);
19039            }
19040        }
19041    }
19042
19043    void updateUserConfigurationLocked() {
19044        final Configuration configuration = new Configuration(getGlobalConfiguration());
19045        final int currentUserId = mUserController.getCurrentUserIdLocked();
19046        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19047                currentUserId, Settings.System.canWrite(mContext));
19048        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19049                false /* persistent */, currentUserId, false /* deferResume */);
19050    }
19051
19052    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19053            boolean initLocale) {
19054        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19055    }
19056
19057    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19058            boolean initLocale, boolean deferResume) {
19059        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19060        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19061                UserHandle.USER_NULL, deferResume);
19062    }
19063
19064    // To cache the list of supported system locales
19065    private String[] mSupportedSystemLocales = null;
19066
19067    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19068            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19069        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19070                deferResume, null /* result */);
19071    }
19072
19073    /**
19074     * Do either or both things: (1) change the current configuration, and (2)
19075     * make sure the given activity is running with the (now) current
19076     * configuration.  Returns true if the activity has been left running, or
19077     * false if <var>starting</var> is being destroyed to match the new
19078     * configuration.
19079     *
19080     * @param userId is only used when persistent parameter is set to true to persist configuration
19081     *               for that particular user
19082     */
19083    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19084            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19085            UpdateConfigurationResult result) {
19086        int changes = 0;
19087        boolean kept = true;
19088
19089        if (mWindowManager != null) {
19090            mWindowManager.deferSurfaceLayout();
19091        }
19092        try {
19093            if (values != null) {
19094                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19095                        deferResume);
19096            }
19097
19098            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19099        } finally {
19100            if (mWindowManager != null) {
19101                mWindowManager.continueSurfaceLayout();
19102            }
19103        }
19104
19105        if (result != null) {
19106            result.changes = changes;
19107            result.activityRelaunched = !kept;
19108        }
19109        return kept;
19110    }
19111
19112    /** Update default (global) configuration and notify listeners about changes. */
19113    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19114            boolean persistent, int userId, boolean deferResume) {
19115        mTempConfig.setTo(getGlobalConfiguration());
19116        final int changes = mTempConfig.updateFrom(values);
19117        if (changes == 0) {
19118            return 0;
19119        }
19120
19121        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19122                "Updating global configuration to: " + values);
19123
19124        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19125
19126        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19127            final LocaleList locales = values.getLocales();
19128            int bestLocaleIndex = 0;
19129            if (locales.size() > 1) {
19130                if (mSupportedSystemLocales == null) {
19131                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19132                }
19133                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19134            }
19135            SystemProperties.set("persist.sys.locale",
19136                    locales.get(bestLocaleIndex).toLanguageTag());
19137            LocaleList.setDefault(locales, bestLocaleIndex);
19138            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19139                    locales.get(bestLocaleIndex)));
19140        }
19141
19142        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19143        mTempConfig.seq = mConfigurationSeq;
19144
19145        // Update stored global config and notify everyone about the change.
19146        mStackSupervisor.onConfigurationChanged(mTempConfig);
19147
19148        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19149        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19150        mUsageStatsService.reportConfigurationChange(mTempConfig,
19151                mUserController.getCurrentUserIdLocked());
19152
19153        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19154        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
19155
19156        AttributeCache ac = AttributeCache.instance();
19157        if (ac != null) {
19158            ac.updateConfiguration(mTempConfig);
19159        }
19160
19161        // Make sure all resources in our process are updated right now, so that anyone who is going
19162        // to retrieve resource values after we return will be sure to get the new ones. This is
19163        // especially important during boot, where the first config change needs to guarantee all
19164        // resources have that config before following boot code is executed.
19165        mSystemThread.applyConfigurationToResources(mTempConfig);
19166
19167        // We need another copy of global config because we're scheduling some calls instead of
19168        // running them in place. We need to be sure that object we send will be handled unchanged.
19169        final Configuration configCopy = new Configuration(mTempConfig);
19170        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19171            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19172            msg.obj = configCopy;
19173            msg.arg1 = userId;
19174            mHandler.sendMessage(msg);
19175        }
19176
19177        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19178            ProcessRecord app = mLruProcesses.get(i);
19179            try {
19180                if (app.thread != null) {
19181                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19182                            + app.processName + " new config " + configCopy);
19183                    app.thread.scheduleConfigurationChanged(configCopy);
19184                }
19185            } catch (Exception e) {
19186            }
19187        }
19188
19189        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19190        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19191                | Intent.FLAG_RECEIVER_FOREGROUND);
19192        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19193                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19194                UserHandle.USER_ALL);
19195        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19196            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19197            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19198            if (initLocale || !mProcessesReady) {
19199                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19200            }
19201            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19202                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19203                    UserHandle.USER_ALL);
19204        }
19205
19206        // Override configuration of the default display duplicates global config, so we need to
19207        // update it also. This will also notify WindowManager about changes.
19208        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19209                DEFAULT_DISPLAY);
19210
19211        return changes;
19212    }
19213
19214    @Override
19215    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19216        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19217
19218        synchronized (this) {
19219            // Check if display is initialized in AM.
19220            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19221                // Call might come when display is not yet added or has already been removed.
19222                if (DEBUG_CONFIGURATION) {
19223                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19224                            + displayId);
19225                }
19226                return false;
19227            }
19228
19229            if (values == null && mWindowManager != null) {
19230                // sentinel: fetch the current configuration from the window manager
19231                values = mWindowManager.computeNewConfiguration(displayId);
19232            }
19233
19234            if (mWindowManager != null) {
19235                // Update OOM levels based on display size.
19236                mProcessList.applyDisplaySize(mWindowManager);
19237            }
19238
19239            final long origId = Binder.clearCallingIdentity();
19240            try {
19241                if (values != null) {
19242                    Settings.System.clearConfiguration(values);
19243                }
19244                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19245                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19246                return mTmpUpdateConfigurationResult.changes != 0;
19247            } finally {
19248                Binder.restoreCallingIdentity(origId);
19249            }
19250        }
19251    }
19252
19253    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19254            boolean deferResume, int displayId) {
19255        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19256                displayId, null /* result */);
19257    }
19258
19259    /**
19260     * Updates override configuration specific for the selected display. If no config is provided,
19261     * new one will be computed in WM based on current display info.
19262     */
19263    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19264            ActivityRecord starting, boolean deferResume, int displayId,
19265            UpdateConfigurationResult result) {
19266        int changes = 0;
19267        boolean kept = true;
19268
19269        if (mWindowManager != null) {
19270            mWindowManager.deferSurfaceLayout();
19271        }
19272        try {
19273            if (values != null) {
19274                if (displayId == DEFAULT_DISPLAY) {
19275                    // Override configuration of the default display duplicates global config, so
19276                    // we're calling global config update instead for default display. It will also
19277                    // apply the correct override config.
19278                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19279                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19280                } else {
19281                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19282                }
19283            }
19284
19285            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19286        } finally {
19287            if (mWindowManager != null) {
19288                mWindowManager.continueSurfaceLayout();
19289            }
19290        }
19291
19292        if (result != null) {
19293            result.changes = changes;
19294            result.activityRelaunched = !kept;
19295        }
19296        return kept;
19297    }
19298
19299    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19300            int displayId) {
19301        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19302        final int changes = mTempConfig.updateFrom(values);
19303        if (changes == 0) {
19304            return 0;
19305        }
19306
19307        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19308                + " for displayId=" + displayId);
19309        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19310
19311        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19312        if (isDensityChange) {
19313            // Reset the unsupported display size dialog.
19314            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19315
19316            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19317        }
19318
19319        // Update the configuration with WM first and check if any of the stacks need to be resized
19320        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19321        // necessary. This way we don't need to relaunch again afterwards in
19322        // ensureActivityConfigurationLocked().
19323        if (mWindowManager != null) {
19324            final int[] resizedStacks =
19325                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19326            if (resizedStacks != null) {
19327                for (int stackId : resizedStacks) {
19328                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19329                }
19330            }
19331        }
19332
19333        return changes;
19334    }
19335
19336    /** Applies latest configuration and/or visibility updates if needed. */
19337    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19338        boolean kept = true;
19339        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19340        // mainStack is null during startup.
19341        if (mainStack != null) {
19342            if (changes != 0 && starting == null) {
19343                // If the configuration changed, and the caller is not already
19344                // in the process of starting an activity, then find the top
19345                // activity to check if its configuration needs to change.
19346                starting = mainStack.topRunningActivityLocked();
19347            }
19348
19349            if (starting != null) {
19350                kept = starting.ensureActivityConfigurationLocked(changes,
19351                        false /* preserveWindow */);
19352                // And we need to make sure at this point that all other activities
19353                // are made visible with the correct configuration.
19354                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19355                        !PRESERVE_WINDOWS);
19356            }
19357        }
19358
19359        return kept;
19360    }
19361
19362    /** Helper method that requests bounds from WM and applies them to stack. */
19363    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19364        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19365        mStackSupervisor.resizeStackLocked(
19366                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19367                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19368    }
19369
19370    /**
19371     * Decide based on the configuration whether we should show the ANR,
19372     * crash, etc dialogs.  The idea is that if there is no affordance to
19373     * press the on-screen buttons, or the user experience would be more
19374     * greatly impacted than the crash itself, we shouldn't show the dialog.
19375     *
19376     * A thought: SystemUI might also want to get told about this, the Power
19377     * dialog / global actions also might want different behaviors.
19378     */
19379    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19380        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19381                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19382                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19383        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19384        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19385                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19386        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19387    }
19388
19389    @Override
19390    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19391        synchronized (this) {
19392            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19393            if (srec != null) {
19394                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19395            }
19396        }
19397        return false;
19398    }
19399
19400    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19401            Intent resultData) {
19402
19403        synchronized (this) {
19404            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19405            if (r != null) {
19406                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19407            }
19408            return false;
19409        }
19410    }
19411
19412    public int getLaunchedFromUid(IBinder activityToken) {
19413        ActivityRecord srec;
19414        synchronized (this) {
19415            srec = ActivityRecord.forTokenLocked(activityToken);
19416        }
19417        if (srec == null) {
19418            return -1;
19419        }
19420        return srec.launchedFromUid;
19421    }
19422
19423    public String getLaunchedFromPackage(IBinder activityToken) {
19424        ActivityRecord srec;
19425        synchronized (this) {
19426            srec = ActivityRecord.forTokenLocked(activityToken);
19427        }
19428        if (srec == null) {
19429            return null;
19430        }
19431        return srec.launchedFromPackage;
19432    }
19433
19434    // =========================================================
19435    // LIFETIME MANAGEMENT
19436    // =========================================================
19437
19438    // Returns whether the app is receiving broadcast.
19439    // If receiving, fetch all broadcast queues which the app is
19440    // the current [or imminent] receiver on.
19441    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19442            ArraySet<BroadcastQueue> receivingQueues) {
19443        if (!app.curReceivers.isEmpty()) {
19444            for (BroadcastRecord r : app.curReceivers) {
19445                receivingQueues.add(r.queue);
19446            }
19447            return true;
19448        }
19449
19450        // It's not the current receiver, but it might be starting up to become one
19451        for (BroadcastQueue queue : mBroadcastQueues) {
19452            final BroadcastRecord r = queue.mPendingBroadcast;
19453            if (r != null && r.curApp == app) {
19454                // found it; report which queue it's in
19455                receivingQueues.add(queue);
19456            }
19457        }
19458
19459        return !receivingQueues.isEmpty();
19460    }
19461
19462    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19463            int targetUid, ComponentName targetComponent, String targetProcess) {
19464        if (!mTrackingAssociations) {
19465            return null;
19466        }
19467        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19468                = mAssociations.get(targetUid);
19469        if (components == null) {
19470            components = new ArrayMap<>();
19471            mAssociations.put(targetUid, components);
19472        }
19473        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19474        if (sourceUids == null) {
19475            sourceUids = new SparseArray<>();
19476            components.put(targetComponent, sourceUids);
19477        }
19478        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19479        if (sourceProcesses == null) {
19480            sourceProcesses = new ArrayMap<>();
19481            sourceUids.put(sourceUid, sourceProcesses);
19482        }
19483        Association ass = sourceProcesses.get(sourceProcess);
19484        if (ass == null) {
19485            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19486                    targetProcess);
19487            sourceProcesses.put(sourceProcess, ass);
19488        }
19489        ass.mCount++;
19490        ass.mNesting++;
19491        if (ass.mNesting == 1) {
19492            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19493            ass.mLastState = sourceState;
19494        }
19495        return ass;
19496    }
19497
19498    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19499            ComponentName targetComponent) {
19500        if (!mTrackingAssociations) {
19501            return;
19502        }
19503        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19504                = mAssociations.get(targetUid);
19505        if (components == null) {
19506            return;
19507        }
19508        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19509        if (sourceUids == null) {
19510            return;
19511        }
19512        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19513        if (sourceProcesses == null) {
19514            return;
19515        }
19516        Association ass = sourceProcesses.get(sourceProcess);
19517        if (ass == null || ass.mNesting <= 0) {
19518            return;
19519        }
19520        ass.mNesting--;
19521        if (ass.mNesting == 0) {
19522            long uptime = SystemClock.uptimeMillis();
19523            ass.mTime += uptime - ass.mStartTime;
19524            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19525                    += uptime - ass.mLastStateUptime;
19526            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19527        }
19528    }
19529
19530    private void noteUidProcessState(final int uid, final int state) {
19531        mBatteryStatsService.noteUidProcessState(uid, state);
19532        if (mTrackingAssociations) {
19533            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19534                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19535                        = mAssociations.valueAt(i1);
19536                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19537                    SparseArray<ArrayMap<String, Association>> sourceUids
19538                            = targetComponents.valueAt(i2);
19539                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19540                    if (sourceProcesses != null) {
19541                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19542                            Association ass = sourceProcesses.valueAt(i4);
19543                            if (ass.mNesting >= 1) {
19544                                // currently associated
19545                                long uptime = SystemClock.uptimeMillis();
19546                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19547                                        += uptime - ass.mLastStateUptime;
19548                                ass.mLastState = state;
19549                                ass.mLastStateUptime = uptime;
19550                            }
19551                        }
19552                    }
19553                }
19554            }
19555        }
19556    }
19557
19558    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19559            boolean doingAll, long now) {
19560        if (mAdjSeq == app.adjSeq) {
19561            // This adjustment has already been computed.
19562            return app.curRawAdj;
19563        }
19564
19565        if (app.thread == null) {
19566            app.adjSeq = mAdjSeq;
19567            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19568            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19569            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19570        }
19571
19572        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19573        app.adjSource = null;
19574        app.adjTarget = null;
19575        app.empty = false;
19576        app.cached = false;
19577
19578        final int activitiesSize = app.activities.size();
19579
19580        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19581            // The max adjustment doesn't allow this app to be anything
19582            // below foreground, so it is not worth doing work for it.
19583            app.adjType = "fixed";
19584            app.adjSeq = mAdjSeq;
19585            app.curRawAdj = app.maxAdj;
19586            app.foregroundActivities = false;
19587            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19588            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19589            // System processes can do UI, and when they do we want to have
19590            // them trim their memory after the user leaves the UI.  To
19591            // facilitate this, here we need to determine whether or not it
19592            // is currently showing UI.
19593            app.systemNoUi = true;
19594            if (app == TOP_APP) {
19595                app.systemNoUi = false;
19596                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19597                app.adjType = "pers-top-activity";
19598            } else if (app.hasTopUi) {
19599                app.systemNoUi = false;
19600                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19601                app.adjType = "pers-top-ui";
19602            } else if (activitiesSize > 0) {
19603                for (int j = 0; j < activitiesSize; j++) {
19604                    final ActivityRecord r = app.activities.get(j);
19605                    if (r.visible) {
19606                        app.systemNoUi = false;
19607                    }
19608                }
19609            }
19610            if (!app.systemNoUi) {
19611                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19612            }
19613            return (app.curAdj=app.maxAdj);
19614        }
19615
19616        app.systemNoUi = false;
19617
19618        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19619
19620        // Determine the importance of the process, starting with most
19621        // important to least, and assign an appropriate OOM adjustment.
19622        int adj;
19623        int schedGroup;
19624        int procState;
19625        boolean foregroundActivities = false;
19626        mTmpBroadcastQueue.clear();
19627        if (app == TOP_APP) {
19628            // The last app on the list is the foreground app.
19629            adj = ProcessList.FOREGROUND_APP_ADJ;
19630            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19631            app.adjType = "top-activity";
19632            foregroundActivities = true;
19633            procState = PROCESS_STATE_CUR_TOP;
19634        } else if (app.instrumentationClass != null) {
19635            // Don't want to kill running instrumentation.
19636            adj = ProcessList.FOREGROUND_APP_ADJ;
19637            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19638            app.adjType = "instrumentation";
19639            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19640        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
19641            // An app that is currently receiving a broadcast also
19642            // counts as being in the foreground for OOM killer purposes.
19643            // It's placed in a sched group based on the nature of the
19644            // broadcast as reflected by which queue it's active in.
19645            adj = ProcessList.FOREGROUND_APP_ADJ;
19646            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
19647                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19648            app.adjType = "broadcast";
19649            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19650        } else if (app.executingServices.size() > 0) {
19651            // An app that is currently executing a service callback also
19652            // counts as being in the foreground.
19653            adj = ProcessList.FOREGROUND_APP_ADJ;
19654            schedGroup = app.execServicesFg ?
19655                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19656            app.adjType = "exec-service";
19657            procState = ActivityManager.PROCESS_STATE_SERVICE;
19658            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19659        } else {
19660            // As far as we know the process is empty.  We may change our mind later.
19661            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19662            // At this point we don't actually know the adjustment.  Use the cached adj
19663            // value that the caller wants us to.
19664            adj = cachedAdj;
19665            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19666            app.cached = true;
19667            app.empty = true;
19668            app.adjType = "cch-empty";
19669        }
19670
19671        // Examine all activities if not already foreground.
19672        if (!foregroundActivities && activitiesSize > 0) {
19673            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19674            for (int j = 0; j < activitiesSize; j++) {
19675                final ActivityRecord r = app.activities.get(j);
19676                if (r.app != app) {
19677                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19678                            + " instead of expected " + app);
19679                    if (r.app == null || (r.app.uid == app.uid)) {
19680                        // Only fix things up when they look sane
19681                        r.app = app;
19682                    } else {
19683                        continue;
19684                    }
19685                }
19686                if (r.visible) {
19687                    // App has a visible activity; only upgrade adjustment.
19688                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19689                        adj = ProcessList.VISIBLE_APP_ADJ;
19690                        app.adjType = "visible";
19691                    }
19692                    if (procState > PROCESS_STATE_CUR_TOP) {
19693                        procState = PROCESS_STATE_CUR_TOP;
19694                    }
19695                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19696                    app.cached = false;
19697                    app.empty = false;
19698                    foregroundActivities = true;
19699                    if (r.task != null && minLayer > 0) {
19700                        final int layer = r.task.mLayerRank;
19701                        if (layer >= 0 && minLayer > layer) {
19702                            minLayer = layer;
19703                        }
19704                    }
19705                    break;
19706                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19707                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19708                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19709                        app.adjType = "pausing";
19710                    }
19711                    if (procState > PROCESS_STATE_CUR_TOP) {
19712                        procState = PROCESS_STATE_CUR_TOP;
19713                    }
19714                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19715                    app.cached = false;
19716                    app.empty = false;
19717                    foregroundActivities = true;
19718                } else if (r.state == ActivityState.STOPPING) {
19719                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19720                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19721                        app.adjType = "stopping";
19722                    }
19723                    // For the process state, we will at this point consider the
19724                    // process to be cached.  It will be cached either as an activity
19725                    // or empty depending on whether the activity is finishing.  We do
19726                    // this so that we can treat the process as cached for purposes of
19727                    // memory trimming (determing current memory level, trim command to
19728                    // send to process) since there can be an arbitrary number of stopping
19729                    // processes and they should soon all go into the cached state.
19730                    if (!r.finishing) {
19731                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19732                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19733                        }
19734                    }
19735                    app.cached = false;
19736                    app.empty = false;
19737                    foregroundActivities = true;
19738                } else {
19739                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19740                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19741                        app.adjType = "cch-act";
19742                    }
19743                }
19744            }
19745            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19746                adj += minLayer;
19747            }
19748        }
19749
19750        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19751                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19752            if (app.foregroundServices) {
19753                // The user is aware of this app, so make it visible.
19754                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19755                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19756                app.cached = false;
19757                app.adjType = "fg-service";
19758                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19759            } else if (app.forcingToForeground != null) {
19760                // The user is aware of this app, so make it visible.
19761                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19762                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19763                app.cached = false;
19764                app.adjType = "force-fg";
19765                app.adjSource = app.forcingToForeground;
19766                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19767            }
19768        }
19769
19770        if (app == mHeavyWeightProcess) {
19771            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19772                // We don't want to kill the current heavy-weight process.
19773                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19774                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19775                app.cached = false;
19776                app.adjType = "heavy";
19777            }
19778            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19779                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19780            }
19781        }
19782
19783        if (app == mHomeProcess) {
19784            if (adj > ProcessList.HOME_APP_ADJ) {
19785                // This process is hosting what we currently consider to be the
19786                // home app, so we don't want to let it go into the background.
19787                adj = ProcessList.HOME_APP_ADJ;
19788                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19789                app.cached = false;
19790                app.adjType = "home";
19791            }
19792            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19793                procState = ActivityManager.PROCESS_STATE_HOME;
19794            }
19795        }
19796
19797        if (app == mPreviousProcess && app.activities.size() > 0) {
19798            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19799                // This was the previous process that showed UI to the user.
19800                // We want to try to keep it around more aggressively, to give
19801                // a good experience around switching between two apps.
19802                adj = ProcessList.PREVIOUS_APP_ADJ;
19803                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19804                app.cached = false;
19805                app.adjType = "previous";
19806            }
19807            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19808                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19809            }
19810        }
19811
19812        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19813                + " reason=" + app.adjType);
19814
19815        // By default, we use the computed adjustment.  It may be changed if
19816        // there are applications dependent on our services or providers, but
19817        // this gives us a baseline and makes sure we don't get into an
19818        // infinite recursion.
19819        app.adjSeq = mAdjSeq;
19820        app.curRawAdj = adj;
19821        app.hasStartedServices = false;
19822
19823        if (mBackupTarget != null && app == mBackupTarget.app) {
19824            // If possible we want to avoid killing apps while they're being backed up
19825            if (adj > ProcessList.BACKUP_APP_ADJ) {
19826                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19827                adj = ProcessList.BACKUP_APP_ADJ;
19828                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19829                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19830                }
19831                app.adjType = "backup";
19832                app.cached = false;
19833            }
19834            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19835                procState = ActivityManager.PROCESS_STATE_BACKUP;
19836            }
19837        }
19838
19839        boolean mayBeTop = false;
19840
19841        for (int is = app.services.size()-1;
19842                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19843                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19844                        || procState > ActivityManager.PROCESS_STATE_TOP);
19845                is--) {
19846            ServiceRecord s = app.services.valueAt(is);
19847            if (s.startRequested) {
19848                app.hasStartedServices = true;
19849                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19850                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19851                }
19852                if (app.hasShownUi && app != mHomeProcess) {
19853                    // If this process has shown some UI, let it immediately
19854                    // go to the LRU list because it may be pretty heavy with
19855                    // UI stuff.  We'll tag it with a label just to help
19856                    // debug and understand what is going on.
19857                    if (adj > ProcessList.SERVICE_ADJ) {
19858                        app.adjType = "cch-started-ui-services";
19859                    }
19860                } else {
19861                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19862                        // This service has seen some activity within
19863                        // recent memory, so we will keep its process ahead
19864                        // of the background processes.
19865                        if (adj > ProcessList.SERVICE_ADJ) {
19866                            adj = ProcessList.SERVICE_ADJ;
19867                            app.adjType = "started-services";
19868                            app.cached = false;
19869                        }
19870                    }
19871                    // If we have let the service slide into the background
19872                    // state, still have some text describing what it is doing
19873                    // even though the service no longer has an impact.
19874                    if (adj > ProcessList.SERVICE_ADJ) {
19875                        app.adjType = "cch-started-services";
19876                    }
19877                }
19878            }
19879
19880            for (int conni = s.connections.size()-1;
19881                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19882                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19883                            || procState > ActivityManager.PROCESS_STATE_TOP);
19884                    conni--) {
19885                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19886                for (int i = 0;
19887                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19888                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19889                                || procState > ActivityManager.PROCESS_STATE_TOP);
19890                        i++) {
19891                    // XXX should compute this based on the max of
19892                    // all connected clients.
19893                    ConnectionRecord cr = clist.get(i);
19894                    if (cr.binding.client == app) {
19895                        // Binding to ourself is not interesting.
19896                        continue;
19897                    }
19898
19899                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19900                        ProcessRecord client = cr.binding.client;
19901                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19902                                TOP_APP, doingAll, now);
19903                        int clientProcState = client.curProcState;
19904                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19905                            // If the other app is cached for any reason, for purposes here
19906                            // we are going to consider it empty.  The specific cached state
19907                            // doesn't propagate except under certain conditions.
19908                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19909                        }
19910                        String adjType = null;
19911                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19912                            // Not doing bind OOM management, so treat
19913                            // this guy more like a started service.
19914                            if (app.hasShownUi && app != mHomeProcess) {
19915                                // If this process has shown some UI, let it immediately
19916                                // go to the LRU list because it may be pretty heavy with
19917                                // UI stuff.  We'll tag it with a label just to help
19918                                // debug and understand what is going on.
19919                                if (adj > clientAdj) {
19920                                    adjType = "cch-bound-ui-services";
19921                                }
19922                                app.cached = false;
19923                                clientAdj = adj;
19924                                clientProcState = procState;
19925                            } else {
19926                                if (now >= (s.lastActivity
19927                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19928                                    // This service has not seen activity within
19929                                    // recent memory, so allow it to drop to the
19930                                    // LRU list if there is no other reason to keep
19931                                    // it around.  We'll also tag it with a label just
19932                                    // to help debug and undertand what is going on.
19933                                    if (adj > clientAdj) {
19934                                        adjType = "cch-bound-services";
19935                                    }
19936                                    clientAdj = adj;
19937                                }
19938                            }
19939                        }
19940                        if (adj > clientAdj) {
19941                            // If this process has recently shown UI, and
19942                            // the process that is binding to it is less
19943                            // important than being visible, then we don't
19944                            // care about the binding as much as we care
19945                            // about letting this process get into the LRU
19946                            // list to be killed and restarted if needed for
19947                            // memory.
19948                            if (app.hasShownUi && app != mHomeProcess
19949                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19950                                adjType = "cch-bound-ui-services";
19951                            } else {
19952                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19953                                        |Context.BIND_IMPORTANT)) != 0) {
19954                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19955                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19956                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19957                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19958                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19959                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19960                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19961                                    adj = clientAdj;
19962                                } else {
19963                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19964                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19965                                    }
19966                                }
19967                                if (!client.cached) {
19968                                    app.cached = false;
19969                                }
19970                                adjType = "service";
19971                            }
19972                        }
19973                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19974                            // This will treat important bound services identically to
19975                            // the top app, which may behave differently than generic
19976                            // foreground work.
19977                            if (client.curSchedGroup > schedGroup) {
19978                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19979                                    schedGroup = client.curSchedGroup;
19980                                } else {
19981                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19982                                }
19983                            }
19984                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19985                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19986                                    // Special handling of clients who are in the top state.
19987                                    // We *may* want to consider this process to be in the
19988                                    // top state as well, but only if there is not another
19989                                    // reason for it to be running.  Being on the top is a
19990                                    // special state, meaning you are specifically running
19991                                    // for the current top app.  If the process is already
19992                                    // running in the background for some other reason, it
19993                                    // is more important to continue considering it to be
19994                                    // in the background state.
19995                                    mayBeTop = true;
19996                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19997                                } else {
19998                                    // Special handling for above-top states (persistent
19999                                    // processes).  These should not bring the current process
20000                                    // into the top state, since they are not on top.  Instead
20001                                    // give them the best state after that.
20002                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20003                                        clientProcState =
20004                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20005                                    } else if (mWakefulness
20006                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20007                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20008                                                    != 0) {
20009                                        clientProcState =
20010                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20011                                    } else {
20012                                        clientProcState =
20013                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20014                                    }
20015                                }
20016                            }
20017                        } else {
20018                            if (clientProcState <
20019                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20020                                clientProcState =
20021                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20022                            }
20023                        }
20024                        if (procState > clientProcState) {
20025                            procState = clientProcState;
20026                        }
20027                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20028                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20029                            app.pendingUiClean = true;
20030                        }
20031                        if (adjType != null) {
20032                            app.adjType = adjType;
20033                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20034                                    .REASON_SERVICE_IN_USE;
20035                            app.adjSource = cr.binding.client;
20036                            app.adjSourceProcState = clientProcState;
20037                            app.adjTarget = s.name;
20038                        }
20039                    }
20040                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20041                        app.treatLikeActivity = true;
20042                    }
20043                    final ActivityRecord a = cr.activity;
20044                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20045                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20046                            (a.visible || a.state == ActivityState.RESUMED ||
20047                             a.state == ActivityState.PAUSING)) {
20048                            adj = ProcessList.FOREGROUND_APP_ADJ;
20049                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20050                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20051                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20052                                } else {
20053                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20054                                }
20055                            }
20056                            app.cached = false;
20057                            app.adjType = "service";
20058                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20059                                    .REASON_SERVICE_IN_USE;
20060                            app.adjSource = a;
20061                            app.adjSourceProcState = procState;
20062                            app.adjTarget = s.name;
20063                        }
20064                    }
20065                }
20066            }
20067        }
20068
20069        for (int provi = app.pubProviders.size()-1;
20070                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20071                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20072                        || procState > ActivityManager.PROCESS_STATE_TOP);
20073                provi--) {
20074            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20075            for (int i = cpr.connections.size()-1;
20076                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20077                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20078                            || procState > ActivityManager.PROCESS_STATE_TOP);
20079                    i--) {
20080                ContentProviderConnection conn = cpr.connections.get(i);
20081                ProcessRecord client = conn.client;
20082                if (client == app) {
20083                    // Being our own client is not interesting.
20084                    continue;
20085                }
20086                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20087                int clientProcState = client.curProcState;
20088                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20089                    // If the other app is cached for any reason, for purposes here
20090                    // we are going to consider it empty.
20091                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20092                }
20093                if (adj > clientAdj) {
20094                    if (app.hasShownUi && app != mHomeProcess
20095                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20096                        app.adjType = "cch-ui-provider";
20097                    } else {
20098                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20099                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20100                        app.adjType = "provider";
20101                    }
20102                    app.cached &= client.cached;
20103                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20104                            .REASON_PROVIDER_IN_USE;
20105                    app.adjSource = client;
20106                    app.adjSourceProcState = clientProcState;
20107                    app.adjTarget = cpr.name;
20108                }
20109                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20110                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20111                        // Special handling of clients who are in the top state.
20112                        // We *may* want to consider this process to be in the
20113                        // top state as well, but only if there is not another
20114                        // reason for it to be running.  Being on the top is a
20115                        // special state, meaning you are specifically running
20116                        // for the current top app.  If the process is already
20117                        // running in the background for some other reason, it
20118                        // is more important to continue considering it to be
20119                        // in the background state.
20120                        mayBeTop = true;
20121                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20122                    } else {
20123                        // Special handling for above-top states (persistent
20124                        // processes).  These should not bring the current process
20125                        // into the top state, since they are not on top.  Instead
20126                        // give them the best state after that.
20127                        clientProcState =
20128                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20129                    }
20130                }
20131                if (procState > clientProcState) {
20132                    procState = clientProcState;
20133                }
20134                if (client.curSchedGroup > schedGroup) {
20135                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20136                }
20137            }
20138            // If the provider has external (non-framework) process
20139            // dependencies, ensure that its adjustment is at least
20140            // FOREGROUND_APP_ADJ.
20141            if (cpr.hasExternalProcessHandles()) {
20142                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20143                    adj = ProcessList.FOREGROUND_APP_ADJ;
20144                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20145                    app.cached = false;
20146                    app.adjType = "provider";
20147                    app.adjTarget = cpr.name;
20148                }
20149                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20150                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20151                }
20152            }
20153        }
20154
20155        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20156            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20157                adj = ProcessList.PREVIOUS_APP_ADJ;
20158                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20159                app.cached = false;
20160                app.adjType = "provider";
20161            }
20162            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20163                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20164            }
20165        }
20166
20167        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20168            // A client of one of our services or providers is in the top state.  We
20169            // *may* want to be in the top state, but not if we are already running in
20170            // the background for some other reason.  For the decision here, we are going
20171            // to pick out a few specific states that we want to remain in when a client
20172            // is top (states that tend to be longer-term) and otherwise allow it to go
20173            // to the top state.
20174            switch (procState) {
20175                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20176                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20177                case ActivityManager.PROCESS_STATE_SERVICE:
20178                    // These all are longer-term states, so pull them up to the top
20179                    // of the background states, but not all the way to the top state.
20180                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20181                    break;
20182                default:
20183                    // Otherwise, top is a better choice, so take it.
20184                    procState = ActivityManager.PROCESS_STATE_TOP;
20185                    break;
20186            }
20187        }
20188
20189        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20190            if (app.hasClientActivities) {
20191                // This is a cached process, but with client activities.  Mark it so.
20192                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20193                app.adjType = "cch-client-act";
20194            } else if (app.treatLikeActivity) {
20195                // This is a cached process, but somebody wants us to treat it like it has
20196                // an activity, okay!
20197                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20198                app.adjType = "cch-as-act";
20199            }
20200        }
20201
20202        if (adj == ProcessList.SERVICE_ADJ) {
20203            if (doingAll) {
20204                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20205                mNewNumServiceProcs++;
20206                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20207                if (!app.serviceb) {
20208                    // This service isn't far enough down on the LRU list to
20209                    // normally be a B service, but if we are low on RAM and it
20210                    // is large we want to force it down since we would prefer to
20211                    // keep launcher over it.
20212                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20213                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20214                        app.serviceHighRam = true;
20215                        app.serviceb = true;
20216                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20217                    } else {
20218                        mNewNumAServiceProcs++;
20219                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20220                    }
20221                } else {
20222                    app.serviceHighRam = false;
20223                }
20224            }
20225            if (app.serviceb) {
20226                adj = ProcessList.SERVICE_B_ADJ;
20227            }
20228        }
20229
20230        app.curRawAdj = adj;
20231
20232        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20233        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20234        if (adj > app.maxAdj) {
20235            adj = app.maxAdj;
20236            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20237                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20238            }
20239        }
20240
20241        // Do final modification to adj.  Everything we do between here and applying
20242        // the final setAdj must be done in this function, because we will also use
20243        // it when computing the final cached adj later.  Note that we don't need to
20244        // worry about this for max adj above, since max adj will always be used to
20245        // keep it out of the cached vaues.
20246        app.curAdj = app.modifyRawOomAdj(adj);
20247        app.curSchedGroup = schedGroup;
20248        app.curProcState = procState;
20249        app.foregroundActivities = foregroundActivities;
20250
20251        return app.curRawAdj;
20252    }
20253
20254    /**
20255     * Record new PSS sample for a process.
20256     */
20257    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20258            long now) {
20259        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20260                swapPss * 1024);
20261        proc.lastPssTime = now;
20262        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20263        if (DEBUG_PSS) Slog.d(TAG_PSS,
20264                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20265                + " state=" + ProcessList.makeProcStateString(procState));
20266        if (proc.initialIdlePss == 0) {
20267            proc.initialIdlePss = pss;
20268        }
20269        proc.lastPss = pss;
20270        proc.lastSwapPss = swapPss;
20271        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20272            proc.lastCachedPss = pss;
20273            proc.lastCachedSwapPss = swapPss;
20274        }
20275
20276        final SparseArray<Pair<Long, String>> watchUids
20277                = mMemWatchProcesses.getMap().get(proc.processName);
20278        Long check = null;
20279        if (watchUids != null) {
20280            Pair<Long, String> val = watchUids.get(proc.uid);
20281            if (val == null) {
20282                val = watchUids.get(0);
20283            }
20284            if (val != null) {
20285                check = val.first;
20286            }
20287        }
20288        if (check != null) {
20289            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20290                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20291                if (!isDebuggable) {
20292                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20293                        isDebuggable = true;
20294                    }
20295                }
20296                if (isDebuggable) {
20297                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20298                    final ProcessRecord myProc = proc;
20299                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20300                    mMemWatchDumpProcName = proc.processName;
20301                    mMemWatchDumpFile = heapdumpFile.toString();
20302                    mMemWatchDumpPid = proc.pid;
20303                    mMemWatchDumpUid = proc.uid;
20304                    BackgroundThread.getHandler().post(new Runnable() {
20305                        @Override
20306                        public void run() {
20307                            revokeUriPermission(ActivityThread.currentActivityThread()
20308                                            .getApplicationThread(),
20309                                    DumpHeapActivity.JAVA_URI,
20310                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20311                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20312                                    UserHandle.myUserId());
20313                            ParcelFileDescriptor fd = null;
20314                            try {
20315                                heapdumpFile.delete();
20316                                fd = ParcelFileDescriptor.open(heapdumpFile,
20317                                        ParcelFileDescriptor.MODE_CREATE |
20318                                                ParcelFileDescriptor.MODE_TRUNCATE |
20319                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20320                                                ParcelFileDescriptor.MODE_APPEND);
20321                                IApplicationThread thread = myProc.thread;
20322                                if (thread != null) {
20323                                    try {
20324                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20325                                                "Requesting dump heap from "
20326                                                + myProc + " to " + heapdumpFile);
20327                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20328                                    } catch (RemoteException e) {
20329                                    }
20330                                }
20331                            } catch (FileNotFoundException e) {
20332                                e.printStackTrace();
20333                            } finally {
20334                                if (fd != null) {
20335                                    try {
20336                                        fd.close();
20337                                    } catch (IOException e) {
20338                                    }
20339                                }
20340                            }
20341                        }
20342                    });
20343                } else {
20344                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20345                            + ", but debugging not enabled");
20346                }
20347            }
20348        }
20349    }
20350
20351    /**
20352     * Schedule PSS collection of a process.
20353     */
20354    void requestPssLocked(ProcessRecord proc, int procState) {
20355        if (mPendingPssProcesses.contains(proc)) {
20356            return;
20357        }
20358        if (mPendingPssProcesses.size() == 0) {
20359            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20360        }
20361        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20362        proc.pssProcState = procState;
20363        mPendingPssProcesses.add(proc);
20364    }
20365
20366    /**
20367     * Schedule PSS collection of all processes.
20368     */
20369    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20370        if (!always) {
20371            if (now < (mLastFullPssTime +
20372                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20373                return;
20374            }
20375        }
20376        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20377        mLastFullPssTime = now;
20378        mFullPssPending = true;
20379        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20380        mPendingPssProcesses.clear();
20381        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20382            ProcessRecord app = mLruProcesses.get(i);
20383            if (app.thread == null
20384                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20385                continue;
20386            }
20387            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20388                app.pssProcState = app.setProcState;
20389                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20390                        mTestPssMode, isSleepingLocked(), now);
20391                mPendingPssProcesses.add(app);
20392            }
20393        }
20394        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20395    }
20396
20397    public void setTestPssMode(boolean enabled) {
20398        synchronized (this) {
20399            mTestPssMode = enabled;
20400            if (enabled) {
20401                // Whenever we enable the mode, we want to take a snapshot all of current
20402                // process mem use.
20403                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20404            }
20405        }
20406    }
20407
20408    /**
20409     * Ask a given process to GC right now.
20410     */
20411    final void performAppGcLocked(ProcessRecord app) {
20412        try {
20413            app.lastRequestedGc = SystemClock.uptimeMillis();
20414            if (app.thread != null) {
20415                if (app.reportLowMemory) {
20416                    app.reportLowMemory = false;
20417                    app.thread.scheduleLowMemory();
20418                } else {
20419                    app.thread.processInBackground();
20420                }
20421            }
20422        } catch (Exception e) {
20423            // whatever.
20424        }
20425    }
20426
20427    /**
20428     * Returns true if things are idle enough to perform GCs.
20429     */
20430    private final boolean canGcNowLocked() {
20431        boolean processingBroadcasts = false;
20432        for (BroadcastQueue q : mBroadcastQueues) {
20433            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20434                processingBroadcasts = true;
20435            }
20436        }
20437        return !processingBroadcasts
20438                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20439    }
20440
20441    /**
20442     * Perform GCs on all processes that are waiting for it, but only
20443     * if things are idle.
20444     */
20445    final void performAppGcsLocked() {
20446        final int N = mProcessesToGc.size();
20447        if (N <= 0) {
20448            return;
20449        }
20450        if (canGcNowLocked()) {
20451            while (mProcessesToGc.size() > 0) {
20452                ProcessRecord proc = mProcessesToGc.remove(0);
20453                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20454                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20455                            <= SystemClock.uptimeMillis()) {
20456                        // To avoid spamming the system, we will GC processes one
20457                        // at a time, waiting a few seconds between each.
20458                        performAppGcLocked(proc);
20459                        scheduleAppGcsLocked();
20460                        return;
20461                    } else {
20462                        // It hasn't been long enough since we last GCed this
20463                        // process...  put it in the list to wait for its time.
20464                        addProcessToGcListLocked(proc);
20465                        break;
20466                    }
20467                }
20468            }
20469
20470            scheduleAppGcsLocked();
20471        }
20472    }
20473
20474    /**
20475     * If all looks good, perform GCs on all processes waiting for them.
20476     */
20477    final void performAppGcsIfAppropriateLocked() {
20478        if (canGcNowLocked()) {
20479            performAppGcsLocked();
20480            return;
20481        }
20482        // Still not idle, wait some more.
20483        scheduleAppGcsLocked();
20484    }
20485
20486    /**
20487     * Schedule the execution of all pending app GCs.
20488     */
20489    final void scheduleAppGcsLocked() {
20490        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20491
20492        if (mProcessesToGc.size() > 0) {
20493            // Schedule a GC for the time to the next process.
20494            ProcessRecord proc = mProcessesToGc.get(0);
20495            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20496
20497            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20498            long now = SystemClock.uptimeMillis();
20499            if (when < (now+GC_TIMEOUT)) {
20500                when = now + GC_TIMEOUT;
20501            }
20502            mHandler.sendMessageAtTime(msg, when);
20503        }
20504    }
20505
20506    /**
20507     * Add a process to the array of processes waiting to be GCed.  Keeps the
20508     * list in sorted order by the last GC time.  The process can't already be
20509     * on the list.
20510     */
20511    final void addProcessToGcListLocked(ProcessRecord proc) {
20512        boolean added = false;
20513        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20514            if (mProcessesToGc.get(i).lastRequestedGc <
20515                    proc.lastRequestedGc) {
20516                added = true;
20517                mProcessesToGc.add(i+1, proc);
20518                break;
20519            }
20520        }
20521        if (!added) {
20522            mProcessesToGc.add(0, proc);
20523        }
20524    }
20525
20526    /**
20527     * Set up to ask a process to GC itself.  This will either do it
20528     * immediately, or put it on the list of processes to gc the next
20529     * time things are idle.
20530     */
20531    final void scheduleAppGcLocked(ProcessRecord app) {
20532        long now = SystemClock.uptimeMillis();
20533        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20534            return;
20535        }
20536        if (!mProcessesToGc.contains(app)) {
20537            addProcessToGcListLocked(app);
20538            scheduleAppGcsLocked();
20539        }
20540    }
20541
20542    final void checkExcessivePowerUsageLocked(boolean doKills) {
20543        updateCpuStatsNow();
20544
20545        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20546        boolean doWakeKills = doKills;
20547        boolean doCpuKills = doKills;
20548        if (mLastPowerCheckRealtime == 0) {
20549            doWakeKills = false;
20550        }
20551        if (mLastPowerCheckUptime == 0) {
20552            doCpuKills = false;
20553        }
20554        if (stats.isScreenOn()) {
20555            doWakeKills = false;
20556        }
20557        final long curRealtime = SystemClock.elapsedRealtime();
20558        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20559        final long curUptime = SystemClock.uptimeMillis();
20560        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20561        mLastPowerCheckRealtime = curRealtime;
20562        mLastPowerCheckUptime = curUptime;
20563        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20564            doWakeKills = false;
20565        }
20566        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20567            doCpuKills = false;
20568        }
20569        int i = mLruProcesses.size();
20570        while (i > 0) {
20571            i--;
20572            ProcessRecord app = mLruProcesses.get(i);
20573            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20574                long wtime;
20575                synchronized (stats) {
20576                    wtime = stats.getProcessWakeTime(app.info.uid,
20577                            app.pid, curRealtime);
20578                }
20579                long wtimeUsed = wtime - app.lastWakeTime;
20580                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20581                if (DEBUG_POWER) {
20582                    StringBuilder sb = new StringBuilder(128);
20583                    sb.append("Wake for ");
20584                    app.toShortString(sb);
20585                    sb.append(": over ");
20586                    TimeUtils.formatDuration(realtimeSince, sb);
20587                    sb.append(" used ");
20588                    TimeUtils.formatDuration(wtimeUsed, sb);
20589                    sb.append(" (");
20590                    sb.append((wtimeUsed*100)/realtimeSince);
20591                    sb.append("%)");
20592                    Slog.i(TAG_POWER, sb.toString());
20593                    sb.setLength(0);
20594                    sb.append("CPU for ");
20595                    app.toShortString(sb);
20596                    sb.append(": over ");
20597                    TimeUtils.formatDuration(uptimeSince, sb);
20598                    sb.append(" used ");
20599                    TimeUtils.formatDuration(cputimeUsed, sb);
20600                    sb.append(" (");
20601                    sb.append((cputimeUsed*100)/uptimeSince);
20602                    sb.append("%)");
20603                    Slog.i(TAG_POWER, sb.toString());
20604                }
20605                // If a process has held a wake lock for more
20606                // than 50% of the time during this period,
20607                // that sounds bad.  Kill!
20608                if (doWakeKills && realtimeSince > 0
20609                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20610                    synchronized (stats) {
20611                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20612                                realtimeSince, wtimeUsed);
20613                    }
20614                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20615                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20616                } else if (doCpuKills && uptimeSince > 0
20617                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20618                    synchronized (stats) {
20619                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20620                                uptimeSince, cputimeUsed);
20621                    }
20622                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20623                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20624                } else {
20625                    app.lastWakeTime = wtime;
20626                    app.lastCpuTime = app.curCpuTime;
20627                }
20628            }
20629        }
20630    }
20631
20632    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20633            long nowElapsed) {
20634        boolean success = true;
20635
20636        if (app.curRawAdj != app.setRawAdj) {
20637            app.setRawAdj = app.curRawAdj;
20638        }
20639
20640        int changes = 0;
20641
20642        if (app.curAdj != app.setAdj) {
20643            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20644            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20645                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20646                    + app.adjType);
20647            app.setAdj = app.curAdj;
20648            app.verifiedAdj = ProcessList.INVALID_ADJ;
20649        }
20650
20651        if (app.setSchedGroup != app.curSchedGroup) {
20652            int oldSchedGroup = app.setSchedGroup;
20653            app.setSchedGroup = app.curSchedGroup;
20654            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20655                    "Setting sched group of " + app.processName
20656                    + " to " + app.curSchedGroup);
20657            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20658                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20659                app.kill(app.waitingToKill, true);
20660                success = false;
20661            } else {
20662                int processGroup;
20663                switch (app.curSchedGroup) {
20664                    case ProcessList.SCHED_GROUP_BACKGROUND:
20665                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20666                        break;
20667                    case ProcessList.SCHED_GROUP_TOP_APP:
20668                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20669                        processGroup = Process.THREAD_GROUP_TOP_APP;
20670                        break;
20671                    default:
20672                        processGroup = Process.THREAD_GROUP_DEFAULT;
20673                        break;
20674                }
20675                long oldId = Binder.clearCallingIdentity();
20676                try {
20677                    Process.setProcessGroup(app.pid, processGroup);
20678                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20679                        // do nothing if we already switched to RT
20680                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20681                            // Switch VR thread for app to SCHED_FIFO
20682                            if (mInVrMode && app.vrThreadTid != 0) {
20683                                try {
20684                                    Process.setThreadScheduler(app.vrThreadTid,
20685                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20686                                } catch (IllegalArgumentException e) {
20687                                    // thread died, ignore
20688                                }
20689                            }
20690                            if (mUseFifoUiScheduling) {
20691                                // Switch UI pipeline for app to SCHED_FIFO
20692                                app.savedPriority = Process.getThreadPriority(app.pid);
20693                                try {
20694                                    Process.setThreadScheduler(app.pid,
20695                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20696                                } catch (IllegalArgumentException e) {
20697                                    // thread died, ignore
20698                                }
20699                                if (app.renderThreadTid != 0) {
20700                                    try {
20701                                        Process.setThreadScheduler(app.renderThreadTid,
20702                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20703                                    } catch (IllegalArgumentException e) {
20704                                        // thread died, ignore
20705                                    }
20706                                    if (DEBUG_OOM_ADJ) {
20707                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20708                                            app.renderThreadTid + ") to FIFO");
20709                                    }
20710                                } else {
20711                                    if (DEBUG_OOM_ADJ) {
20712                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20713                                    }
20714                                }
20715                            } else {
20716                                // Boost priority for top app UI and render threads
20717                                Process.setThreadPriority(app.pid, -10);
20718                                if (app.renderThreadTid != 0) {
20719                                    try {
20720                                        Process.setThreadPriority(app.renderThreadTid, -10);
20721                                    } catch (IllegalArgumentException e) {
20722                                        // thread died, ignore
20723                                    }
20724                                }
20725                            }
20726                        }
20727                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20728                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20729                        // Reset VR thread to SCHED_OTHER
20730                        // Safe to do even if we're not in VR mode
20731                        if (app.vrThreadTid != 0) {
20732                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20733                        }
20734                        if (mUseFifoUiScheduling) {
20735                            // Reset UI pipeline to SCHED_OTHER
20736                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20737                            Process.setThreadPriority(app.pid, app.savedPriority);
20738                            if (app.renderThreadTid != 0) {
20739                                Process.setThreadScheduler(app.renderThreadTid,
20740                                    Process.SCHED_OTHER, 0);
20741                                Process.setThreadPriority(app.renderThreadTid, -4);
20742                            }
20743                        } else {
20744                            // Reset priority for top app UI and render threads
20745                            Process.setThreadPriority(app.pid, 0);
20746                            if (app.renderThreadTid != 0) {
20747                                Process.setThreadPriority(app.renderThreadTid, 0);
20748                            }
20749                        }
20750                    }
20751                } catch (Exception e) {
20752                    Slog.w(TAG, "Failed setting process group of " + app.pid
20753                            + " to " + app.curSchedGroup);
20754                    e.printStackTrace();
20755                } finally {
20756                    Binder.restoreCallingIdentity(oldId);
20757                }
20758            }
20759        }
20760        if (app.repForegroundActivities != app.foregroundActivities) {
20761            app.repForegroundActivities = app.foregroundActivities;
20762            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20763        }
20764        if (app.repProcState != app.curProcState) {
20765            app.repProcState = app.curProcState;
20766            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20767            if (app.thread != null) {
20768                try {
20769                    if (false) {
20770                        //RuntimeException h = new RuntimeException("here");
20771                        Slog.i(TAG, "Sending new process state " + app.repProcState
20772                                + " to " + app /*, h*/);
20773                    }
20774                    app.thread.setProcessState(app.repProcState);
20775                } catch (RemoteException e) {
20776                }
20777            }
20778        }
20779        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20780                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20781            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20782                // Experimental code to more aggressively collect pss while
20783                // running test...  the problem is that this tends to collect
20784                // the data right when a process is transitioning between process
20785                // states, which well tend to give noisy data.
20786                long start = SystemClock.uptimeMillis();
20787                long pss = Debug.getPss(app.pid, mTmpLong, null);
20788                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20789                mPendingPssProcesses.remove(app);
20790                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20791                        + " to " + app.curProcState + ": "
20792                        + (SystemClock.uptimeMillis()-start) + "ms");
20793            }
20794            app.lastStateTime = now;
20795            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20796                    mTestPssMode, isSleepingLocked(), now);
20797            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20798                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20799                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20800                    + (app.nextPssTime-now) + ": " + app);
20801        } else {
20802            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20803                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20804                    mTestPssMode)))) {
20805                requestPssLocked(app, app.setProcState);
20806                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20807                        mTestPssMode, isSleepingLocked(), now);
20808            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20809                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20810        }
20811        if (app.setProcState != app.curProcState) {
20812            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20813                    "Proc state change of " + app.processName
20814                            + " to " + app.curProcState);
20815            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20816            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20817            if (setImportant && !curImportant) {
20818                // This app is no longer something we consider important enough to allow to
20819                // use arbitrary amounts of battery power.  Note
20820                // its current wake lock time to later know to kill it if
20821                // it is not behaving well.
20822                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20823                synchronized (stats) {
20824                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20825                            app.pid, nowElapsed);
20826                }
20827                app.lastCpuTime = app.curCpuTime;
20828
20829            }
20830            // Inform UsageStats of important process state change
20831            // Must be called before updating setProcState
20832            maybeUpdateUsageStatsLocked(app, nowElapsed);
20833
20834            app.setProcState = app.curProcState;
20835            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20836                app.notCachedSinceIdle = false;
20837            }
20838            if (!doingAll) {
20839                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20840            } else {
20841                app.procStateChanged = true;
20842            }
20843        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20844                > USAGE_STATS_INTERACTION_INTERVAL) {
20845            // For apps that sit around for a long time in the interactive state, we need
20846            // to report this at least once a day so they don't go idle.
20847            maybeUpdateUsageStatsLocked(app, nowElapsed);
20848        }
20849
20850        if (changes != 0) {
20851            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20852                    "Changes in " + app + ": " + changes);
20853            int i = mPendingProcessChanges.size()-1;
20854            ProcessChangeItem item = null;
20855            while (i >= 0) {
20856                item = mPendingProcessChanges.get(i);
20857                if (item.pid == app.pid) {
20858                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20859                            "Re-using existing item: " + item);
20860                    break;
20861                }
20862                i--;
20863            }
20864            if (i < 0) {
20865                // No existing item in pending changes; need a new one.
20866                final int NA = mAvailProcessChanges.size();
20867                if (NA > 0) {
20868                    item = mAvailProcessChanges.remove(NA-1);
20869                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20870                            "Retrieving available item: " + item);
20871                } else {
20872                    item = new ProcessChangeItem();
20873                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20874                            "Allocating new item: " + item);
20875                }
20876                item.changes = 0;
20877                item.pid = app.pid;
20878                item.uid = app.info.uid;
20879                if (mPendingProcessChanges.size() == 0) {
20880                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20881                            "*** Enqueueing dispatch processes changed!");
20882                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20883                }
20884                mPendingProcessChanges.add(item);
20885            }
20886            item.changes |= changes;
20887            item.processState = app.repProcState;
20888            item.foregroundActivities = app.repForegroundActivities;
20889            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20890                    "Item " + Integer.toHexString(System.identityHashCode(item))
20891                    + " " + app.toShortString() + ": changes=" + item.changes
20892                    + " procState=" + item.processState
20893                    + " foreground=" + item.foregroundActivities
20894                    + " type=" + app.adjType + " source=" + app.adjSource
20895                    + " target=" + app.adjTarget);
20896        }
20897
20898        return success;
20899    }
20900
20901    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20902        final UidRecord.ChangeItem pendingChange;
20903        if (uidRec == null || uidRec.pendingChange == null) {
20904            if (mPendingUidChanges.size() == 0) {
20905                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20906                        "*** Enqueueing dispatch uid changed!");
20907                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20908            }
20909            final int NA = mAvailUidChanges.size();
20910            if (NA > 0) {
20911                pendingChange = mAvailUidChanges.remove(NA-1);
20912                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20913                        "Retrieving available item: " + pendingChange);
20914            } else {
20915                pendingChange = new UidRecord.ChangeItem();
20916                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20917                        "Allocating new item: " + pendingChange);
20918            }
20919            if (uidRec != null) {
20920                uidRec.pendingChange = pendingChange;
20921                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20922                    // If this uid is going away, and we haven't yet reported it is gone,
20923                    // then do so now.
20924                    change = UidRecord.CHANGE_GONE_IDLE;
20925                }
20926            } else if (uid < 0) {
20927                throw new IllegalArgumentException("No UidRecord or uid");
20928            }
20929            pendingChange.uidRecord = uidRec;
20930            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20931            mPendingUidChanges.add(pendingChange);
20932        } else {
20933            pendingChange = uidRec.pendingChange;
20934            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20935                change = UidRecord.CHANGE_GONE_IDLE;
20936            }
20937        }
20938        pendingChange.change = change;
20939        pendingChange.processState = uidRec != null
20940                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20941        pendingChange.ephemeral = uidRec.ephemeral;
20942
20943        // Directly update the power manager, since we sit on top of it and it is critical
20944        // it be kept in sync (so wake locks will be held as soon as appropriate).
20945        if (mLocalPowerManager != null) {
20946            switch (change) {
20947                case UidRecord.CHANGE_GONE:
20948                case UidRecord.CHANGE_GONE_IDLE:
20949                    mLocalPowerManager.uidGone(pendingChange.uid);
20950                    break;
20951                case UidRecord.CHANGE_IDLE:
20952                    mLocalPowerManager.uidIdle(pendingChange.uid);
20953                    break;
20954                case UidRecord.CHANGE_ACTIVE:
20955                    mLocalPowerManager.uidActive(pendingChange.uid);
20956                    break;
20957                default:
20958                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
20959                            pendingChange.processState);
20960                    break;
20961            }
20962        }
20963    }
20964
20965    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20966            String authority) {
20967        if (app == null) return;
20968        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20969            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20970            if (userState == null) return;
20971            final long now = SystemClock.elapsedRealtime();
20972            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20973            if (lastReported == null || lastReported < now - 60 * 1000L) {
20974                if (mSystemReady) {
20975                    // Cannot touch the user stats if not system ready
20976                    mUsageStatsService.reportContentProviderUsage(
20977                            authority, providerPkgName, app.userId);
20978                }
20979                userState.mProviderLastReportedFg.put(authority, now);
20980            }
20981        }
20982    }
20983
20984    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20985        if (DEBUG_USAGE_STATS) {
20986            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20987                    + "] state changes: old = " + app.setProcState + ", new = "
20988                    + app.curProcState);
20989        }
20990        if (mUsageStatsService == null) {
20991            return;
20992        }
20993        boolean isInteraction;
20994        // To avoid some abuse patterns, we are going to be careful about what we consider
20995        // to be an app interaction.  Being the top activity doesn't count while the display
20996        // is sleeping, nor do short foreground services.
20997        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20998            isInteraction = true;
20999            app.fgInteractionTime = 0;
21000        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21001            if (app.fgInteractionTime == 0) {
21002                app.fgInteractionTime = nowElapsed;
21003                isInteraction = false;
21004            } else {
21005                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21006            }
21007        } else {
21008            // If the app was being forced to the foreground, by say a Toast, then
21009            // no need to treat it as an interaction
21010            isInteraction = app.forcingToForeground == null
21011                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21012            app.fgInteractionTime = 0;
21013        }
21014        if (isInteraction && (!app.reportedInteraction
21015                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21016            app.interactionEventTime = nowElapsed;
21017            String[] packages = app.getPackageList();
21018            if (packages != null) {
21019                for (int i = 0; i < packages.length; i++) {
21020                    mUsageStatsService.reportEvent(packages[i], app.userId,
21021                            UsageEvents.Event.SYSTEM_INTERACTION);
21022                }
21023            }
21024        }
21025        app.reportedInteraction = isInteraction;
21026        if (!isInteraction) {
21027            app.interactionEventTime = 0;
21028        }
21029    }
21030
21031    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21032        if (proc.thread != null) {
21033            if (proc.baseProcessTracker != null) {
21034                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21035            }
21036        }
21037    }
21038
21039    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21040            ProcessRecord TOP_APP, boolean doingAll, long now) {
21041        if (app.thread == null) {
21042            return false;
21043        }
21044
21045        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21046
21047        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21048    }
21049
21050    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21051            boolean oomAdj) {
21052        if (isForeground != proc.foregroundServices) {
21053            proc.foregroundServices = isForeground;
21054            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21055                    proc.info.uid);
21056            if (isForeground) {
21057                if (curProcs == null) {
21058                    curProcs = new ArrayList<ProcessRecord>();
21059                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21060                }
21061                if (!curProcs.contains(proc)) {
21062                    curProcs.add(proc);
21063                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21064                            proc.info.packageName, proc.info.uid);
21065                }
21066            } else {
21067                if (curProcs != null) {
21068                    if (curProcs.remove(proc)) {
21069                        mBatteryStatsService.noteEvent(
21070                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21071                                proc.info.packageName, proc.info.uid);
21072                        if (curProcs.size() <= 0) {
21073                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21074                        }
21075                    }
21076                }
21077            }
21078            if (oomAdj) {
21079                updateOomAdjLocked();
21080            }
21081        }
21082    }
21083
21084    private final ActivityRecord resumedAppLocked() {
21085        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21086        String pkg;
21087        int uid;
21088        if (act != null) {
21089            pkg = act.packageName;
21090            uid = act.info.applicationInfo.uid;
21091        } else {
21092            pkg = null;
21093            uid = -1;
21094        }
21095        // Has the UID or resumed package name changed?
21096        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21097                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21098            if (mCurResumedPackage != null) {
21099                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21100                        mCurResumedPackage, mCurResumedUid);
21101            }
21102            mCurResumedPackage = pkg;
21103            mCurResumedUid = uid;
21104            if (mCurResumedPackage != null) {
21105                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21106                        mCurResumedPackage, mCurResumedUid);
21107            }
21108        }
21109        return act;
21110    }
21111
21112    final boolean updateOomAdjLocked(ProcessRecord app) {
21113        final ActivityRecord TOP_ACT = resumedAppLocked();
21114        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21115        final boolean wasCached = app.cached;
21116
21117        mAdjSeq++;
21118
21119        // This is the desired cached adjusment we want to tell it to use.
21120        // If our app is currently cached, we know it, and that is it.  Otherwise,
21121        // we don't know it yet, and it needs to now be cached we will then
21122        // need to do a complete oom adj.
21123        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21124                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21125        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21126                SystemClock.uptimeMillis());
21127        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21128            // Changed to/from cached state, so apps after it in the LRU
21129            // list may also be changed.
21130            updateOomAdjLocked();
21131        }
21132        return success;
21133    }
21134
21135    final void updateOomAdjLocked() {
21136        final ActivityRecord TOP_ACT = resumedAppLocked();
21137        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21138        final long now = SystemClock.uptimeMillis();
21139        final long nowElapsed = SystemClock.elapsedRealtime();
21140        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21141        final int N = mLruProcesses.size();
21142
21143        if (false) {
21144            RuntimeException e = new RuntimeException();
21145            e.fillInStackTrace();
21146            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21147        }
21148
21149        // Reset state in all uid records.
21150        for (int i=mActiveUids.size()-1; i>=0; i--) {
21151            final UidRecord uidRec = mActiveUids.valueAt(i);
21152            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21153                    "Starting update of " + uidRec);
21154            uidRec.reset();
21155        }
21156
21157        mStackSupervisor.rankTaskLayersIfNeeded();
21158
21159        mAdjSeq++;
21160        mNewNumServiceProcs = 0;
21161        mNewNumAServiceProcs = 0;
21162
21163        final int emptyProcessLimit;
21164        final int cachedProcessLimit;
21165        if (mProcessLimit <= 0) {
21166            emptyProcessLimit = cachedProcessLimit = 0;
21167        } else if (mProcessLimit == 1) {
21168            emptyProcessLimit = 1;
21169            cachedProcessLimit = 0;
21170        } else {
21171            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
21172            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
21173        }
21174
21175        // Let's determine how many processes we have running vs.
21176        // how many slots we have for background processes; we may want
21177        // to put multiple processes in a slot of there are enough of
21178        // them.
21179        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21180                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21181        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21182        if (numEmptyProcs > cachedProcessLimit) {
21183            // If there are more empty processes than our limit on cached
21184            // processes, then use the cached process limit for the factor.
21185            // This ensures that the really old empty processes get pushed
21186            // down to the bottom, so if we are running low on memory we will
21187            // have a better chance at keeping around more cached processes
21188            // instead of a gazillion empty processes.
21189            numEmptyProcs = cachedProcessLimit;
21190        }
21191        int emptyFactor = numEmptyProcs/numSlots;
21192        if (emptyFactor < 1) emptyFactor = 1;
21193        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21194        if (cachedFactor < 1) cachedFactor = 1;
21195        int stepCached = 0;
21196        int stepEmpty = 0;
21197        int numCached = 0;
21198        int numEmpty = 0;
21199        int numTrimming = 0;
21200
21201        mNumNonCachedProcs = 0;
21202        mNumCachedHiddenProcs = 0;
21203
21204        // First update the OOM adjustment for each of the
21205        // application processes based on their current state.
21206        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21207        int nextCachedAdj = curCachedAdj+1;
21208        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21209        int nextEmptyAdj = curEmptyAdj+2;
21210        for (int i=N-1; i>=0; i--) {
21211            ProcessRecord app = mLruProcesses.get(i);
21212            if (!app.killedByAm && app.thread != null) {
21213                app.procStateChanged = false;
21214                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21215
21216                // If we haven't yet assigned the final cached adj
21217                // to the process, do that now.
21218                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21219                    switch (app.curProcState) {
21220                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21221                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21222                            // This process is a cached process holding activities...
21223                            // assign it the next cached value for that type, and then
21224                            // step that cached level.
21225                            app.curRawAdj = curCachedAdj;
21226                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21227                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21228                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21229                                    + ")");
21230                            if (curCachedAdj != nextCachedAdj) {
21231                                stepCached++;
21232                                if (stepCached >= cachedFactor) {
21233                                    stepCached = 0;
21234                                    curCachedAdj = nextCachedAdj;
21235                                    nextCachedAdj += 2;
21236                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21237                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21238                                    }
21239                                }
21240                            }
21241                            break;
21242                        default:
21243                            // For everything else, assign next empty cached process
21244                            // level and bump that up.  Note that this means that
21245                            // long-running services that have dropped down to the
21246                            // cached level will be treated as empty (since their process
21247                            // state is still as a service), which is what we want.
21248                            app.curRawAdj = curEmptyAdj;
21249                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21250                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21251                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21252                                    + ")");
21253                            if (curEmptyAdj != nextEmptyAdj) {
21254                                stepEmpty++;
21255                                if (stepEmpty >= emptyFactor) {
21256                                    stepEmpty = 0;
21257                                    curEmptyAdj = nextEmptyAdj;
21258                                    nextEmptyAdj += 2;
21259                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21260                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21261                                    }
21262                                }
21263                            }
21264                            break;
21265                    }
21266                }
21267
21268                applyOomAdjLocked(app, true, now, nowElapsed);
21269
21270                // Count the number of process types.
21271                switch (app.curProcState) {
21272                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21273                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21274                        mNumCachedHiddenProcs++;
21275                        numCached++;
21276                        if (numCached > cachedProcessLimit) {
21277                            app.kill("cached #" + numCached, true);
21278                        }
21279                        break;
21280                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21281                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21282                                && app.lastActivityTime < oldTime) {
21283                            app.kill("empty for "
21284                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21285                                    / 1000) + "s", true);
21286                        } else {
21287                            numEmpty++;
21288                            if (numEmpty > emptyProcessLimit) {
21289                                app.kill("empty #" + numEmpty, true);
21290                            }
21291                        }
21292                        break;
21293                    default:
21294                        mNumNonCachedProcs++;
21295                        break;
21296                }
21297
21298                if (app.isolated && app.services.size() <= 0) {
21299                    // If this is an isolated process, and there are no
21300                    // services running in it, then the process is no longer
21301                    // needed.  We agressively kill these because we can by
21302                    // definition not re-use the same process again, and it is
21303                    // good to avoid having whatever code was running in them
21304                    // left sitting around after no longer needed.
21305                    app.kill("isolated not needed", true);
21306                } else {
21307                    // Keeping this process, update its uid.
21308                    final UidRecord uidRec = app.uidRecord;
21309                    if (uidRec != null) {
21310                        uidRec.ephemeral = app.info.isEphemeralApp();
21311                        if (uidRec.curProcState > app.curProcState) {
21312                            uidRec.curProcState = app.curProcState;
21313                        }
21314                    }
21315                }
21316
21317                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21318                        && !app.killedByAm) {
21319                    numTrimming++;
21320                }
21321            }
21322        }
21323
21324        mNumServiceProcs = mNewNumServiceProcs;
21325
21326        // Now determine the memory trimming level of background processes.
21327        // Unfortunately we need to start at the back of the list to do this
21328        // properly.  We only do this if the number of background apps we
21329        // are managing to keep around is less than half the maximum we desire;
21330        // if we are keeping a good number around, we'll let them use whatever
21331        // memory they want.
21332        final int numCachedAndEmpty = numCached + numEmpty;
21333        int memFactor;
21334        if (numCached <= ProcessList.TRIM_CACHED_APPS
21335                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21336            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21337                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21338            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21339                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21340            } else {
21341                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21342            }
21343        } else {
21344            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21345        }
21346        // We always allow the memory level to go up (better).  We only allow it to go
21347        // down if we are in a state where that is allowed, *and* the total number of processes
21348        // has gone down since last time.
21349        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21350                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21351                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21352        if (memFactor > mLastMemoryLevel) {
21353            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21354                memFactor = mLastMemoryLevel;
21355                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21356            }
21357        }
21358        if (memFactor != mLastMemoryLevel) {
21359            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21360        }
21361        mLastMemoryLevel = memFactor;
21362        mLastNumProcesses = mLruProcesses.size();
21363        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21364        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21365        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21366            if (mLowRamStartTime == 0) {
21367                mLowRamStartTime = now;
21368            }
21369            int step = 0;
21370            int fgTrimLevel;
21371            switch (memFactor) {
21372                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21373                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21374                    break;
21375                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21376                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21377                    break;
21378                default:
21379                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21380                    break;
21381            }
21382            int factor = numTrimming/3;
21383            int minFactor = 2;
21384            if (mHomeProcess != null) minFactor++;
21385            if (mPreviousProcess != null) minFactor++;
21386            if (factor < minFactor) factor = minFactor;
21387            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21388            for (int i=N-1; i>=0; i--) {
21389                ProcessRecord app = mLruProcesses.get(i);
21390                if (allChanged || app.procStateChanged) {
21391                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21392                    app.procStateChanged = false;
21393                }
21394                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21395                        && !app.killedByAm) {
21396                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21397                        try {
21398                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21399                                    "Trimming memory of " + app.processName + " to " + curLevel);
21400                            app.thread.scheduleTrimMemory(curLevel);
21401                        } catch (RemoteException e) {
21402                        }
21403                        if (false) {
21404                            // For now we won't do this; our memory trimming seems
21405                            // to be good enough at this point that destroying
21406                            // activities causes more harm than good.
21407                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21408                                    && app != mHomeProcess && app != mPreviousProcess) {
21409                                // Need to do this on its own message because the stack may not
21410                                // be in a consistent state at this point.
21411                                // For these apps we will also finish their activities
21412                                // to help them free memory.
21413                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21414                            }
21415                        }
21416                    }
21417                    app.trimMemoryLevel = curLevel;
21418                    step++;
21419                    if (step >= factor) {
21420                        step = 0;
21421                        switch (curLevel) {
21422                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21423                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21424                                break;
21425                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21426                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21427                                break;
21428                        }
21429                    }
21430                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21431                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21432                            && app.thread != null) {
21433                        try {
21434                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21435                                    "Trimming memory of heavy-weight " + app.processName
21436                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21437                            app.thread.scheduleTrimMemory(
21438                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21439                        } catch (RemoteException e) {
21440                        }
21441                    }
21442                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21443                } else {
21444                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21445                            || app.systemNoUi) && app.pendingUiClean) {
21446                        // If this application is now in the background and it
21447                        // had done UI, then give it the special trim level to
21448                        // have it free UI resources.
21449                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21450                        if (app.trimMemoryLevel < level && app.thread != null) {
21451                            try {
21452                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21453                                        "Trimming memory of bg-ui " + app.processName
21454                                        + " to " + level);
21455                                app.thread.scheduleTrimMemory(level);
21456                            } catch (RemoteException e) {
21457                            }
21458                        }
21459                        app.pendingUiClean = false;
21460                    }
21461                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21462                        try {
21463                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21464                                    "Trimming memory of fg " + app.processName
21465                                    + " to " + fgTrimLevel);
21466                            app.thread.scheduleTrimMemory(fgTrimLevel);
21467                        } catch (RemoteException e) {
21468                        }
21469                    }
21470                    app.trimMemoryLevel = fgTrimLevel;
21471                }
21472            }
21473        } else {
21474            if (mLowRamStartTime != 0) {
21475                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21476                mLowRamStartTime = 0;
21477            }
21478            for (int i=N-1; i>=0; i--) {
21479                ProcessRecord app = mLruProcesses.get(i);
21480                if (allChanged || app.procStateChanged) {
21481                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21482                    app.procStateChanged = false;
21483                }
21484                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21485                        || app.systemNoUi) && app.pendingUiClean) {
21486                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21487                            && app.thread != null) {
21488                        try {
21489                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21490                                    "Trimming memory of ui hidden " + app.processName
21491                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21492                            app.thread.scheduleTrimMemory(
21493                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21494                        } catch (RemoteException e) {
21495                        }
21496                    }
21497                    app.pendingUiClean = false;
21498                }
21499                app.trimMemoryLevel = 0;
21500            }
21501        }
21502
21503        if (mAlwaysFinishActivities) {
21504            // Need to do this on its own message because the stack may not
21505            // be in a consistent state at this point.
21506            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21507        }
21508
21509        if (allChanged) {
21510            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21511        }
21512
21513        // Update from any uid changes.
21514        if (mLocalPowerManager != null) {
21515            mLocalPowerManager.startUidChanges();
21516        }
21517        for (int i=mActiveUids.size()-1; i>=0; i--) {
21518            final UidRecord uidRec = mActiveUids.valueAt(i);
21519            int uidChange = UidRecord.CHANGE_PROCSTATE;
21520            if (uidRec.setProcState != uidRec.curProcState) {
21521                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21522                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21523                        + " to " + uidRec.curProcState);
21524                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21525                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21526                        uidRec.lastBackgroundTime = nowElapsed;
21527                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21528                            // Note: the background settle time is in elapsed realtime, while
21529                            // the handler time base is uptime.  All this means is that we may
21530                            // stop background uids later than we had intended, but that only
21531                            // happens because the device was sleeping so we are okay anyway.
21532                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21533                        }
21534                    }
21535                } else {
21536                    if (uidRec.idle) {
21537                        uidChange = UidRecord.CHANGE_ACTIVE;
21538                        uidRec.idle = false;
21539                    }
21540                    uidRec.lastBackgroundTime = 0;
21541                }
21542                uidRec.setProcState = uidRec.curProcState;
21543                enqueueUidChangeLocked(uidRec, -1, uidChange);
21544                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21545            }
21546        }
21547        if (mLocalPowerManager != null) {
21548            mLocalPowerManager.finishUidChanges();
21549        }
21550
21551        if (mProcessStats.shouldWriteNowLocked(now)) {
21552            mHandler.post(new Runnable() {
21553                @Override public void run() {
21554                    synchronized (ActivityManagerService.this) {
21555                        mProcessStats.writeStateAsyncLocked();
21556                    }
21557                }
21558            });
21559        }
21560
21561        if (DEBUG_OOM_ADJ) {
21562            final long duration = SystemClock.uptimeMillis() - now;
21563            if (false) {
21564                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21565                        new RuntimeException("here").fillInStackTrace());
21566            } else {
21567                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21568            }
21569        }
21570    }
21571
21572    @Override
21573    public void makePackageIdle(String packageName, int userId) {
21574        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
21575                != PackageManager.PERMISSION_GRANTED) {
21576            String msg = "Permission Denial: makePackageIdle() from pid="
21577                    + Binder.getCallingPid()
21578                    + ", uid=" + Binder.getCallingUid()
21579                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
21580            Slog.w(TAG, msg);
21581            throw new SecurityException(msg);
21582        }
21583        final int callingPid = Binder.getCallingPid();
21584        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
21585                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
21586        long callingId = Binder.clearCallingIdentity();
21587        synchronized(this) {
21588            try {
21589                IPackageManager pm = AppGlobals.getPackageManager();
21590                int pkgUid = -1;
21591                try {
21592                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
21593                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
21594                } catch (RemoteException e) {
21595                }
21596                if (pkgUid == -1) {
21597                    throw new IllegalArgumentException("Unknown package name " + packageName);
21598                }
21599
21600                if (mLocalPowerManager != null) {
21601                    mLocalPowerManager.startUidChanges();
21602                }
21603                final int appId = UserHandle.getAppId(pkgUid);
21604                final int N = mActiveUids.size();
21605                for (int i=N-1; i>=0; i--) {
21606                    final UidRecord uidRec = mActiveUids.valueAt(i);
21607                    final long bgTime = uidRec.lastBackgroundTime;
21608                    if (bgTime > 0 && !uidRec.idle) {
21609                        if (UserHandle.getAppId(uidRec.uid) == appId) {
21610                            if (userId == UserHandle.USER_ALL ||
21611                                    userId == UserHandle.getUserId(uidRec.uid)) {
21612                                uidRec.idle = true;
21613                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
21614                                        + " from package " + packageName + " user " + userId);
21615                                doStopUidLocked(uidRec.uid, uidRec);
21616                            }
21617                        }
21618                    }
21619                }
21620            } finally {
21621                if (mLocalPowerManager != null) {
21622                    mLocalPowerManager.finishUidChanges();
21623                }
21624                Binder.restoreCallingIdentity(callingId);
21625            }
21626        }
21627    }
21628
21629    final void idleUids() {
21630        synchronized (this) {
21631            final int N = mActiveUids.size();
21632            if (N <= 0) {
21633                return;
21634            }
21635            final long nowElapsed = SystemClock.elapsedRealtime();
21636            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21637            long nextTime = 0;
21638            if (mLocalPowerManager != null) {
21639                mLocalPowerManager.startUidChanges();
21640            }
21641            for (int i=N-1; i>=0; i--) {
21642                final UidRecord uidRec = mActiveUids.valueAt(i);
21643                final long bgTime = uidRec.lastBackgroundTime;
21644                if (bgTime > 0 && !uidRec.idle) {
21645                    if (bgTime <= maxBgTime) {
21646                        uidRec.idle = true;
21647                        doStopUidLocked(uidRec.uid, uidRec);
21648                    } else {
21649                        if (nextTime == 0 || nextTime > bgTime) {
21650                            nextTime = bgTime;
21651                        }
21652                    }
21653                }
21654            }
21655            if (mLocalPowerManager != null) {
21656                mLocalPowerManager.finishUidChanges();
21657            }
21658            if (nextTime > 0) {
21659                mHandler.removeMessages(IDLE_UIDS_MSG);
21660                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21661                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21662            }
21663        }
21664    }
21665
21666    final void runInBackgroundDisabled(int uid) {
21667        synchronized (this) {
21668            UidRecord uidRec = mActiveUids.get(uid);
21669            if (uidRec != null) {
21670                // This uid is actually running...  should it be considered background now?
21671                if (uidRec.idle) {
21672                    doStopUidLocked(uidRec.uid, uidRec);
21673                }
21674            } else {
21675                // This uid isn't actually running...  still send a report about it being "stopped".
21676                doStopUidLocked(uid, null);
21677            }
21678        }
21679    }
21680
21681    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21682        mServices.stopInBackgroundLocked(uid);
21683        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21684    }
21685
21686    final void trimApplications() {
21687        synchronized (this) {
21688            int i;
21689
21690            // First remove any unused application processes whose package
21691            // has been removed.
21692            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21693                final ProcessRecord app = mRemovedProcesses.get(i);
21694                if (app.activities.size() == 0
21695                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21696                    Slog.i(
21697                        TAG, "Exiting empty application process "
21698                        + app.toShortString() + " ("
21699                        + (app.thread != null ? app.thread.asBinder() : null)
21700                        + ")\n");
21701                    if (app.pid > 0 && app.pid != MY_PID) {
21702                        app.kill("empty", false);
21703                    } else {
21704                        try {
21705                            app.thread.scheduleExit();
21706                        } catch (Exception e) {
21707                            // Ignore exceptions.
21708                        }
21709                    }
21710                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21711                    mRemovedProcesses.remove(i);
21712
21713                    if (app.persistent) {
21714                        addAppLocked(app.info, false, null /* ABI override */);
21715                    }
21716                }
21717            }
21718
21719            // Now update the oom adj for all processes.
21720            updateOomAdjLocked();
21721        }
21722    }
21723
21724    /** This method sends the specified signal to each of the persistent apps */
21725    public void signalPersistentProcesses(int sig) throws RemoteException {
21726        if (sig != Process.SIGNAL_USR1) {
21727            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21728        }
21729
21730        synchronized (this) {
21731            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21732                    != PackageManager.PERMISSION_GRANTED) {
21733                throw new SecurityException("Requires permission "
21734                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21735            }
21736
21737            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21738                ProcessRecord r = mLruProcesses.get(i);
21739                if (r.thread != null && r.persistent) {
21740                    Process.sendSignal(r.pid, sig);
21741                }
21742            }
21743        }
21744    }
21745
21746    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21747        if (proc == null || proc == mProfileProc) {
21748            proc = mProfileProc;
21749            profileType = mProfileType;
21750            clearProfilerLocked();
21751        }
21752        if (proc == null) {
21753            return;
21754        }
21755        try {
21756            proc.thread.profilerControl(false, null, profileType);
21757        } catch (RemoteException e) {
21758            throw new IllegalStateException("Process disappeared");
21759        }
21760    }
21761
21762    private void clearProfilerLocked() {
21763        if (mProfileFd != null) {
21764            try {
21765                mProfileFd.close();
21766            } catch (IOException e) {
21767            }
21768        }
21769        mProfileApp = null;
21770        mProfileProc = null;
21771        mProfileFile = null;
21772        mProfileType = 0;
21773        mAutoStopProfiler = false;
21774        mSamplingInterval = 0;
21775    }
21776
21777    public boolean profileControl(String process, int userId, boolean start,
21778            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21779
21780        try {
21781            synchronized (this) {
21782                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21783                // its own permission.
21784                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21785                        != PackageManager.PERMISSION_GRANTED) {
21786                    throw new SecurityException("Requires permission "
21787                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21788                }
21789
21790                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21791                    throw new IllegalArgumentException("null profile info or fd");
21792                }
21793
21794                ProcessRecord proc = null;
21795                if (process != null) {
21796                    proc = findProcessLocked(process, userId, "profileControl");
21797                }
21798
21799                if (start && (proc == null || proc.thread == null)) {
21800                    throw new IllegalArgumentException("Unknown process: " + process);
21801                }
21802
21803                if (start) {
21804                    stopProfilerLocked(null, 0);
21805                    setProfileApp(proc.info, proc.processName, profilerInfo);
21806                    mProfileProc = proc;
21807                    mProfileType = profileType;
21808                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21809                    try {
21810                        fd = fd.dup();
21811                    } catch (IOException e) {
21812                        fd = null;
21813                    }
21814                    profilerInfo.profileFd = fd;
21815                    proc.thread.profilerControl(start, profilerInfo, profileType);
21816                    fd = null;
21817                    mProfileFd = null;
21818                } else {
21819                    stopProfilerLocked(proc, profileType);
21820                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21821                        try {
21822                            profilerInfo.profileFd.close();
21823                        } catch (IOException e) {
21824                        }
21825                    }
21826                }
21827
21828                return true;
21829            }
21830        } catch (RemoteException e) {
21831            throw new IllegalStateException("Process disappeared");
21832        } finally {
21833            if (profilerInfo != null && profilerInfo.profileFd != null) {
21834                try {
21835                    profilerInfo.profileFd.close();
21836                } catch (IOException e) {
21837                }
21838            }
21839        }
21840    }
21841
21842    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21843        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21844                userId, true, ALLOW_FULL_ONLY, callName, null);
21845        ProcessRecord proc = null;
21846        try {
21847            int pid = Integer.parseInt(process);
21848            synchronized (mPidsSelfLocked) {
21849                proc = mPidsSelfLocked.get(pid);
21850            }
21851        } catch (NumberFormatException e) {
21852        }
21853
21854        if (proc == null) {
21855            ArrayMap<String, SparseArray<ProcessRecord>> all
21856                    = mProcessNames.getMap();
21857            SparseArray<ProcessRecord> procs = all.get(process);
21858            if (procs != null && procs.size() > 0) {
21859                proc = procs.valueAt(0);
21860                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21861                    for (int i=1; i<procs.size(); i++) {
21862                        ProcessRecord thisProc = procs.valueAt(i);
21863                        if (thisProc.userId == userId) {
21864                            proc = thisProc;
21865                            break;
21866                        }
21867                    }
21868                }
21869            }
21870        }
21871
21872        return proc;
21873    }
21874
21875    public boolean dumpHeap(String process, int userId, boolean managed,
21876            String path, ParcelFileDescriptor fd) throws RemoteException {
21877
21878        try {
21879            synchronized (this) {
21880                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21881                // its own permission (same as profileControl).
21882                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21883                        != PackageManager.PERMISSION_GRANTED) {
21884                    throw new SecurityException("Requires permission "
21885                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21886                }
21887
21888                if (fd == null) {
21889                    throw new IllegalArgumentException("null fd");
21890                }
21891
21892                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21893                if (proc == null || proc.thread == null) {
21894                    throw new IllegalArgumentException("Unknown process: " + process);
21895                }
21896
21897                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21898                if (!isDebuggable) {
21899                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21900                        throw new SecurityException("Process not debuggable: " + proc);
21901                    }
21902                }
21903
21904                proc.thread.dumpHeap(managed, path, fd);
21905                fd = null;
21906                return true;
21907            }
21908        } catch (RemoteException e) {
21909            throw new IllegalStateException("Process disappeared");
21910        } finally {
21911            if (fd != null) {
21912                try {
21913                    fd.close();
21914                } catch (IOException e) {
21915                }
21916            }
21917        }
21918    }
21919
21920    @Override
21921    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21922            String reportPackage) {
21923        if (processName != null) {
21924            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21925                    "setDumpHeapDebugLimit()");
21926        } else {
21927            synchronized (mPidsSelfLocked) {
21928                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21929                if (proc == null) {
21930                    throw new SecurityException("No process found for calling pid "
21931                            + Binder.getCallingPid());
21932                }
21933                if (!Build.IS_DEBUGGABLE
21934                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21935                    throw new SecurityException("Not running a debuggable build");
21936                }
21937                processName = proc.processName;
21938                uid = proc.uid;
21939                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21940                    throw new SecurityException("Package " + reportPackage + " is not running in "
21941                            + proc);
21942                }
21943            }
21944        }
21945        synchronized (this) {
21946            if (maxMemSize > 0) {
21947                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21948            } else {
21949                if (uid != 0) {
21950                    mMemWatchProcesses.remove(processName, uid);
21951                } else {
21952                    mMemWatchProcesses.getMap().remove(processName);
21953                }
21954            }
21955        }
21956    }
21957
21958    @Override
21959    public void dumpHeapFinished(String path) {
21960        synchronized (this) {
21961            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21962                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21963                        + " does not match last pid " + mMemWatchDumpPid);
21964                return;
21965            }
21966            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21967                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21968                        + " does not match last path " + mMemWatchDumpFile);
21969                return;
21970            }
21971            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21972            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21973        }
21974    }
21975
21976    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21977    public void monitor() {
21978        synchronized (this) { }
21979    }
21980
21981    void onCoreSettingsChange(Bundle settings) {
21982        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21983            ProcessRecord processRecord = mLruProcesses.get(i);
21984            try {
21985                if (processRecord.thread != null) {
21986                    processRecord.thread.setCoreSettings(settings);
21987                }
21988            } catch (RemoteException re) {
21989                /* ignore */
21990            }
21991        }
21992    }
21993
21994    // Multi-user methods
21995
21996    /**
21997     * Start user, if its not already running, but don't bring it to foreground.
21998     */
21999    @Override
22000    public boolean startUserInBackground(final int userId) {
22001        return mUserController.startUser(userId, /* foreground */ false);
22002    }
22003
22004    @Override
22005    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
22006        return mUserController.unlockUser(userId, token, secret, listener);
22007    }
22008
22009    @Override
22010    public boolean switchUser(final int targetUserId) {
22011        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
22012        int currentUserId;
22013        UserInfo targetUserInfo;
22014        synchronized (this) {
22015            currentUserId = mUserController.getCurrentUserIdLocked();
22016            targetUserInfo = mUserController.getUserInfo(targetUserId);
22017            if (targetUserId == currentUserId) {
22018                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
22019                return true;
22020            }
22021            if (targetUserInfo == null) {
22022                Slog.w(TAG, "No user info for user #" + targetUserId);
22023                return false;
22024            }
22025            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
22026                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
22027                        + " when device is in demo mode");
22028                return false;
22029            }
22030            if (!targetUserInfo.supportsSwitchTo()) {
22031                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
22032                return false;
22033            }
22034            if (targetUserInfo.isManagedProfile()) {
22035                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
22036                return false;
22037            }
22038            mUserController.setTargetUserIdLocked(targetUserId);
22039        }
22040        if (mUserController.mUserSwitchUiEnabled) {
22041            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
22042            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
22043            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
22044            mUiHandler.sendMessage(mHandler.obtainMessage(
22045                    START_USER_SWITCH_UI_MSG, userNames));
22046        } else {
22047            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
22048            mHandler.sendMessage(mHandler.obtainMessage(
22049                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
22050        }
22051        return true;
22052    }
22053
22054    void scheduleStartProfilesLocked() {
22055        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
22056            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
22057                    DateUtils.SECOND_IN_MILLIS);
22058        }
22059    }
22060
22061    @Override
22062    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
22063        return mUserController.stopUser(userId, force, callback);
22064    }
22065
22066    @Override
22067    public UserInfo getCurrentUser() {
22068        return mUserController.getCurrentUser();
22069    }
22070
22071    String getStartedUserState(int userId) {
22072        synchronized (this) {
22073            final UserState userState = mUserController.getStartedUserStateLocked(userId);
22074            return UserState.stateToString(userState.state);
22075        }
22076    }
22077
22078    @Override
22079    public boolean isUserRunning(int userId, int flags) {
22080        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
22081                && checkCallingPermission(INTERACT_ACROSS_USERS)
22082                    != PackageManager.PERMISSION_GRANTED) {
22083            String msg = "Permission Denial: isUserRunning() from pid="
22084                    + Binder.getCallingPid()
22085                    + ", uid=" + Binder.getCallingUid()
22086                    + " requires " + INTERACT_ACROSS_USERS;
22087            Slog.w(TAG, msg);
22088            throw new SecurityException(msg);
22089        }
22090        synchronized (this) {
22091            return mUserController.isUserRunningLocked(userId, flags);
22092        }
22093    }
22094
22095    @Override
22096    public int[] getRunningUserIds() {
22097        if (checkCallingPermission(INTERACT_ACROSS_USERS)
22098                != PackageManager.PERMISSION_GRANTED) {
22099            String msg = "Permission Denial: isUserRunning() from pid="
22100                    + Binder.getCallingPid()
22101                    + ", uid=" + Binder.getCallingUid()
22102                    + " requires " + INTERACT_ACROSS_USERS;
22103            Slog.w(TAG, msg);
22104            throw new SecurityException(msg);
22105        }
22106        synchronized (this) {
22107            return mUserController.getStartedUserArrayLocked();
22108        }
22109    }
22110
22111    @Override
22112    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
22113        mUserController.registerUserSwitchObserver(observer, name);
22114    }
22115
22116    @Override
22117    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
22118        mUserController.unregisterUserSwitchObserver(observer);
22119    }
22120
22121    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
22122        if (info == null) return null;
22123        ApplicationInfo newInfo = new ApplicationInfo(info);
22124        newInfo.initForUser(userId);
22125        return newInfo;
22126    }
22127
22128    public boolean isUserStopped(int userId) {
22129        synchronized (this) {
22130            return mUserController.getStartedUserStateLocked(userId) == null;
22131        }
22132    }
22133
22134    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
22135        if (aInfo == null
22136                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
22137            return aInfo;
22138        }
22139
22140        ActivityInfo info = new ActivityInfo(aInfo);
22141        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
22142        return info;
22143    }
22144
22145    private boolean processSanityChecksLocked(ProcessRecord process) {
22146        if (process == null || process.thread == null) {
22147            return false;
22148        }
22149
22150        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22151        if (!isDebuggable) {
22152            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22153                return false;
22154            }
22155        }
22156
22157        return true;
22158    }
22159
22160    public boolean startBinderTracking() throws RemoteException {
22161        synchronized (this) {
22162            mBinderTransactionTrackingEnabled = true;
22163            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22164            // permission (same as profileControl).
22165            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22166                    != PackageManager.PERMISSION_GRANTED) {
22167                throw new SecurityException("Requires permission "
22168                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22169            }
22170
22171            for (int i = 0; i < mLruProcesses.size(); i++) {
22172                ProcessRecord process = mLruProcesses.get(i);
22173                if (!processSanityChecksLocked(process)) {
22174                    continue;
22175                }
22176                try {
22177                    process.thread.startBinderTracking();
22178                } catch (RemoteException e) {
22179                    Log.v(TAG, "Process disappared");
22180                }
22181            }
22182            return true;
22183        }
22184    }
22185
22186    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
22187        try {
22188            synchronized (this) {
22189                mBinderTransactionTrackingEnabled = false;
22190                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22191                // permission (same as profileControl).
22192                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22193                        != PackageManager.PERMISSION_GRANTED) {
22194                    throw new SecurityException("Requires permission "
22195                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22196                }
22197
22198                if (fd == null) {
22199                    throw new IllegalArgumentException("null fd");
22200                }
22201
22202                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
22203                pw.println("Binder transaction traces for all processes.\n");
22204                for (ProcessRecord process : mLruProcesses) {
22205                    if (!processSanityChecksLocked(process)) {
22206                        continue;
22207                    }
22208
22209                    pw.println("Traces for process: " + process.processName);
22210                    pw.flush();
22211                    try {
22212                        TransferPipe tp = new TransferPipe();
22213                        try {
22214                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
22215                            tp.go(fd.getFileDescriptor());
22216                        } finally {
22217                            tp.kill();
22218                        }
22219                    } catch (IOException e) {
22220                        pw.println("Failure while dumping IPC traces from " + process +
22221                                ".  Exception: " + e);
22222                        pw.flush();
22223                    } catch (RemoteException e) {
22224                        pw.println("Got a RemoteException while dumping IPC traces from " +
22225                                process + ".  Exception: " + e);
22226                        pw.flush();
22227                    }
22228                }
22229                fd = null;
22230                return true;
22231            }
22232        } finally {
22233            if (fd != null) {
22234                try {
22235                    fd.close();
22236                } catch (IOException e) {
22237                }
22238            }
22239        }
22240    }
22241
22242    private final class LocalService extends ActivityManagerInternal {
22243        @Override
22244        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
22245                int targetUserId) {
22246            synchronized (ActivityManagerService.this) {
22247                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
22248                        targetPkg, intent, null, targetUserId);
22249            }
22250        }
22251
22252        @Override
22253        public String checkContentProviderAccess(String authority, int userId) {
22254            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
22255        }
22256
22257        @Override
22258        public void onWakefulnessChanged(int wakefulness) {
22259            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22260        }
22261
22262        @Override
22263        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22264                String processName, String abiOverride, int uid, Runnable crashHandler) {
22265            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22266                    processName, abiOverride, uid, crashHandler);
22267        }
22268
22269        @Override
22270        public SleepToken acquireSleepToken(String tag) {
22271            Preconditions.checkNotNull(tag);
22272
22273            synchronized (ActivityManagerService.this) {
22274                SleepTokenImpl token = new SleepTokenImpl(tag);
22275                mSleepTokens.add(token);
22276                updateSleepIfNeededLocked();
22277                return token;
22278            }
22279        }
22280
22281        @Override
22282        public ComponentName getHomeActivityForUser(int userId) {
22283            synchronized (ActivityManagerService.this) {
22284                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22285                return homeActivity == null ? null : homeActivity.realActivity;
22286            }
22287        }
22288
22289        @Override
22290        public void onUserRemoved(int userId) {
22291            synchronized (ActivityManagerService.this) {
22292                ActivityManagerService.this.onUserStoppedLocked(userId);
22293            }
22294        }
22295
22296        @Override
22297        public void onLocalVoiceInteractionStarted(IBinder activity,
22298                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22299            synchronized (ActivityManagerService.this) {
22300                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22301                        voiceSession, voiceInteractor);
22302            }
22303        }
22304
22305        @Override
22306        public void notifyStartingWindowDrawn() {
22307            synchronized (ActivityManagerService.this) {
22308                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22309            }
22310        }
22311
22312        @Override
22313        public void notifyAppTransitionStarting(int reason) {
22314            synchronized (ActivityManagerService.this) {
22315                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22316            }
22317        }
22318
22319        @Override
22320        public void notifyAppTransitionFinished() {
22321            synchronized (ActivityManagerService.this) {
22322                mStackSupervisor.notifyAppTransitionDone();
22323            }
22324        }
22325
22326        @Override
22327        public void notifyAppTransitionCancelled() {
22328            synchronized (ActivityManagerService.this) {
22329                mStackSupervisor.notifyAppTransitionDone();
22330            }
22331        }
22332
22333        @Override
22334        public List<IBinder> getTopVisibleActivities() {
22335            synchronized (ActivityManagerService.this) {
22336                return mStackSupervisor.getTopVisibleActivities();
22337            }
22338        }
22339
22340        @Override
22341        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22342            synchronized (ActivityManagerService.this) {
22343                mStackSupervisor.setDockedStackMinimized(minimized);
22344            }
22345        }
22346
22347        @Override
22348        public void killForegroundAppsForUser(int userHandle) {
22349            synchronized (ActivityManagerService.this) {
22350                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22351                final int NP = mProcessNames.getMap().size();
22352                for (int ip = 0; ip < NP; ip++) {
22353                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22354                    final int NA = apps.size();
22355                    for (int ia = 0; ia < NA; ia++) {
22356                        final ProcessRecord app = apps.valueAt(ia);
22357                        if (app.persistent) {
22358                            // We don't kill persistent processes.
22359                            continue;
22360                        }
22361                        if (app.removed) {
22362                            procs.add(app);
22363                        } else if (app.userId == userHandle && app.foregroundActivities) {
22364                            app.removed = true;
22365                            procs.add(app);
22366                        }
22367                    }
22368                }
22369
22370                final int N = procs.size();
22371                for (int i = 0; i < N; i++) {
22372                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22373                }
22374            }
22375        }
22376
22377        @Override
22378        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22379            if (!(target instanceof PendingIntentRecord)) {
22380                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22381                return;
22382            }
22383            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22384        }
22385
22386        @Override
22387        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22388                int userId) {
22389            Preconditions.checkNotNull(values, "Configuration must not be null");
22390            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22391            synchronized (ActivityManagerService.this) {
22392                updateConfigurationLocked(values, null, false, true, userId,
22393                        false /* deferResume */);
22394            }
22395        }
22396
22397        @Override
22398        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22399                Bundle bOptions) {
22400            Preconditions.checkNotNull(intents, "intents");
22401            final String[] resolvedTypes = new String[intents.length];
22402            for (int i = 0; i < intents.length; i++) {
22403                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22404            }
22405
22406            // UID of the package on user userId.
22407            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22408            // packageUid may not be initialized.
22409            int packageUid = 0;
22410            try {
22411                packageUid = AppGlobals.getPackageManager().getPackageUid(
22412                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22413            } catch (RemoteException e) {
22414                // Shouldn't happen.
22415            }
22416
22417            synchronized (ActivityManagerService.this) {
22418                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22419                        /*resultTo*/ null, bOptions, userId);
22420            }
22421        }
22422
22423        @Override
22424        public int getUidProcessState(int uid) {
22425            return getUidState(uid);
22426        }
22427
22428        @Override
22429        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
22430            synchronized (ActivityManagerService.this) {
22431
22432                // We might change the visibilities here, so prepare an empty app transition which
22433                // might be overridden later if we actually change visibilities.
22434                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
22435                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22436                mWindowManager.executeAppTransition();
22437            }
22438            if (callback != null) {
22439                callback.run();
22440            }
22441        }
22442
22443        @Override
22444        public boolean isSystemReady() {
22445            // no need to synchronize(this) just to read & return the value
22446            return mSystemReady;
22447        }
22448
22449        @Override
22450        public void notifyKeyguardTrustedChanged() {
22451            synchronized (ActivityManagerService.this) {
22452                if (mKeyguardController.isKeyguardShowing()) {
22453                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22454                }
22455            }
22456        }
22457    }
22458
22459    private final class SleepTokenImpl extends SleepToken {
22460        private final String mTag;
22461        private final long mAcquireTime;
22462
22463        public SleepTokenImpl(String tag) {
22464            mTag = tag;
22465            mAcquireTime = SystemClock.uptimeMillis();
22466        }
22467
22468        @Override
22469        public void release() {
22470            synchronized (ActivityManagerService.this) {
22471                if (mSleepTokens.remove(this)) {
22472                    updateSleepIfNeededLocked();
22473                }
22474            }
22475        }
22476
22477        @Override
22478        public String toString() {
22479            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22480        }
22481    }
22482
22483    /**
22484     * An implementation of IAppTask, that allows an app to manage its own tasks via
22485     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22486     * only the process that calls getAppTasks() can call the AppTask methods.
22487     */
22488    class AppTaskImpl extends IAppTask.Stub {
22489        private int mTaskId;
22490        private int mCallingUid;
22491
22492        public AppTaskImpl(int taskId, int callingUid) {
22493            mTaskId = taskId;
22494            mCallingUid = callingUid;
22495        }
22496
22497        private void checkCaller() {
22498            if (mCallingUid != Binder.getCallingUid()) {
22499                throw new SecurityException("Caller " + mCallingUid
22500                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22501            }
22502        }
22503
22504        @Override
22505        public void finishAndRemoveTask() {
22506            checkCaller();
22507
22508            synchronized (ActivityManagerService.this) {
22509                long origId = Binder.clearCallingIdentity();
22510                try {
22511                    // We remove the task from recents to preserve backwards
22512                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
22513                            REMOVE_FROM_RECENTS)) {
22514                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22515                    }
22516                } finally {
22517                    Binder.restoreCallingIdentity(origId);
22518                }
22519            }
22520        }
22521
22522        @Override
22523        public ActivityManager.RecentTaskInfo getTaskInfo() {
22524            checkCaller();
22525
22526            synchronized (ActivityManagerService.this) {
22527                long origId = Binder.clearCallingIdentity();
22528                try {
22529                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22530                    if (tr == null) {
22531                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22532                    }
22533                    return createRecentTaskInfoFromTaskRecord(tr);
22534                } finally {
22535                    Binder.restoreCallingIdentity(origId);
22536                }
22537            }
22538        }
22539
22540        @Override
22541        public void moveToFront() {
22542            checkCaller();
22543            // Will bring task to front if it already has a root activity.
22544            final long origId = Binder.clearCallingIdentity();
22545            try {
22546                synchronized (this) {
22547                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22548                }
22549            } finally {
22550                Binder.restoreCallingIdentity(origId);
22551            }
22552        }
22553
22554        @Override
22555        public int startActivity(IBinder whoThread, String callingPackage,
22556                Intent intent, String resolvedType, Bundle bOptions) {
22557            checkCaller();
22558
22559            int callingUser = UserHandle.getCallingUserId();
22560            TaskRecord tr;
22561            IApplicationThread appThread;
22562            synchronized (ActivityManagerService.this) {
22563                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22564                if (tr == null) {
22565                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22566                }
22567                appThread = IApplicationThread.Stub.asInterface(whoThread);
22568                if (appThread == null) {
22569                    throw new IllegalArgumentException("Bad app thread " + appThread);
22570                }
22571            }
22572            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22573                    resolvedType, null, null, null, null, 0, 0, null, null,
22574                    null, bOptions, false, callingUser, null, tr);
22575        }
22576
22577        @Override
22578        public void setExcludeFromRecents(boolean exclude) {
22579            checkCaller();
22580
22581            synchronized (ActivityManagerService.this) {
22582                long origId = Binder.clearCallingIdentity();
22583                try {
22584                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22585                    if (tr == null) {
22586                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22587                    }
22588                    Intent intent = tr.getBaseIntent();
22589                    if (exclude) {
22590                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22591                    } else {
22592                        intent.setFlags(intent.getFlags()
22593                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22594                    }
22595                } finally {
22596                    Binder.restoreCallingIdentity(origId);
22597                }
22598            }
22599        }
22600    }
22601
22602    /**
22603     * Kill processes for the user with id userId and that depend on the package named packageName
22604     */
22605    @Override
22606    public void killPackageDependents(String packageName, int userId) {
22607        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22608        if (packageName == null) {
22609            throw new NullPointerException(
22610                    "Cannot kill the dependents of a package without its name.");
22611        }
22612
22613        long callingId = Binder.clearCallingIdentity();
22614        IPackageManager pm = AppGlobals.getPackageManager();
22615        int pkgUid = -1;
22616        try {
22617            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22618        } catch (RemoteException e) {
22619        }
22620        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22621            throw new IllegalArgumentException(
22622                    "Cannot kill dependents of non-existing package " + packageName);
22623        }
22624        try {
22625            synchronized(this) {
22626                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22627                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22628                        "dep: " + packageName);
22629            }
22630        } finally {
22631            Binder.restoreCallingIdentity(callingId);
22632        }
22633    }
22634
22635    @Override
22636    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22637        final int userId = intent.getCreatorUserHandle().getIdentifier();
22638        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22639            return false;
22640        }
22641        IIntentSender target = intent.getTarget();
22642        if (!(target instanceof PendingIntentRecord)) {
22643            return false;
22644        }
22645        final PendingIntentRecord record = (PendingIntentRecord) target;
22646        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22647                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22648        // For direct boot aware activities, they can be shown without triggering a work challenge
22649        // before the profile user is unlocked.
22650        return rInfo != null && rInfo.activityInfo != null;
22651    }
22652
22653    @Override
22654    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
22655            throws RemoteException {
22656        final long callingId = Binder.clearCallingIdentity();
22657        try {
22658            mKeyguardController.dismissKeyguard(token, callback);
22659        } finally {
22660            Binder.restoreCallingIdentity(callingId);
22661        }
22662    }
22663
22664    /**
22665     * Attach an agent to the specified process (proces name or PID)
22666     */
22667    public void attachAgent(String process, String path) {
22668        try {
22669            synchronized (this) {
22670                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22671                if (proc == null || proc.thread == null) {
22672                    throw new IllegalArgumentException("Unknown process: " + process);
22673                }
22674
22675                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22676                if (!isDebuggable) {
22677                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22678                        throw new SecurityException("Process not debuggable: " + proc);
22679                    }
22680                }
22681
22682                proc.thread.attachAgent(path);
22683            }
22684        } catch (RemoteException e) {
22685            throw new IllegalStateException("Process disappeared");
22686        }
22687    }
22688}
22689