ActivityManagerService.java revision 45b2070637b9a95b366eee486c6483954f84a767
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;
260
261import dalvik.system.VMRuntime;
262
263import libcore.io.IoUtils;
264import libcore.util.EmptyArray;
265
266import static android.Manifest.permission.CHANGE_CONFIGURATION;
267import static android.Manifest.permission.INTERACT_ACROSS_USERS;
268import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
269import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
270import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
271import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
272import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
273import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
274import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
275import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
276import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
277import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
278import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
279import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
280import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
281import static android.content.pm.PackageManager.GET_PROVIDERS;
282import static android.content.pm.PackageManager.MATCH_ANY_USER;
283import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
284import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
285import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
286import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
287import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
288import static android.content.pm.PackageManager.PERMISSION_GRANTED;
289import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
290import static android.os.Build.VERSION_CODES.N;
291import static android.os.Process.PROC_CHAR;
292import static android.os.Process.PROC_OUT_LONG;
293import static android.os.Process.PROC_PARENS;
294import static android.os.Process.PROC_SPACE_TERM;
295import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
296import static android.provider.Settings.Global.DEBUG_APP;
297import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
298import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
299import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
300import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
301import static android.provider.Settings.System.FONT_SCALE;
302import static android.view.Display.DEFAULT_DISPLAY;
303
304import static com.android.internal.util.XmlUtils.readBooleanAttribute;
305import static com.android.internal.util.XmlUtils.readIntAttribute;
306import static com.android.internal.util.XmlUtils.readLongAttribute;
307import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
308import static com.android.internal.util.XmlUtils.writeIntAttribute;
309import static com.android.internal.util.XmlUtils.writeLongAttribute;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
329import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
330import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
331import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
332import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
333import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
334import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
335import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
336import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
338import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
339import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
340import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
341import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
353import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
354import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
355import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
356import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
357import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
358import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
359import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
360import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
361import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
362import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
363import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
364import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
365import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
366import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
367import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
368import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
369import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
370import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
371import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
372import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
373import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
374import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
375import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
376import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
377import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
378import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
379import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
380import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
381import static com.android.server.wm.AppTransition.TRANSIT_NONE;
382import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
383import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
384import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
385import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
386import static org.xmlpull.v1.XmlPullParser.START_TAG;
387
388public class ActivityManagerService extends IActivityManager.Stub
389        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
390
391    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
392    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
393    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
394    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
395    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
396    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
397    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
398    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
399    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
400    private static final String TAG_LRU = TAG + POSTFIX_LRU;
401    private static final String TAG_MU = TAG + POSTFIX_MU;
402    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
403    private static final String TAG_POWER = TAG + POSTFIX_POWER;
404    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
405    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
406    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
407    private static final String TAG_PSS = TAG + POSTFIX_PSS;
408    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
409    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
410    private static final String TAG_STACK = TAG + POSTFIX_STACK;
411    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
412    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
413    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
414    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
415    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
416
417    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
418    // here so that while the job scheduler can depend on AMS, the other way around
419    // need not be the case.
420    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
421
422    /** Control over CPU and battery monitoring */
423    // write battery stats every 30 minutes.
424    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
425    static final boolean MONITOR_CPU_USAGE = true;
426    // don't sample cpu less than every 5 seconds.
427    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
428    // wait possibly forever for next cpu sample.
429    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
430    static final boolean MONITOR_THREAD_CPU_USAGE = false;
431
432    // The flags that are set for all calls we make to the package manager.
433    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
434
435    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
436
437    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
438
439    // Amount of time after a call to stopAppSwitches() during which we will
440    // prevent further untrusted switches from happening.
441    static final long APP_SWITCH_DELAY_TIME = 5*1000;
442
443    // How long we wait for a launched process to attach to the activity manager
444    // before we decide it's never going to come up for real.
445    static final int PROC_START_TIMEOUT = 10*1000;
446    // How long we wait for an attached process to publish its content providers
447    // before we decide it must be hung.
448    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
449
450    // How long we will retain processes hosting content providers in the "last activity"
451    // state before allowing them to drop down to the regular cached LRU list.  This is
452    // to avoid thrashing of provider processes under low memory situations.
453    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
454
455    // How long we wait for a launched process to attach to the activity manager
456    // before we decide it's never going to come up for real, when the process was
457    // started with a wrapper for instrumentation (such as Valgrind) because it
458    // could take much longer than usual.
459    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
460
461    // How long to wait after going idle before forcing apps to GC.
462    static final int GC_TIMEOUT = 5*1000;
463
464    // The minimum amount of time between successive GC requests for a process.
465    static final int GC_MIN_INTERVAL = 60*1000;
466
467    // The minimum amount of time between successive PSS requests for a process.
468    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
469
470    // The minimum amount of time between successive PSS requests for a process
471    // when the request is due to the memory state being lowered.
472    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
473
474    // The rate at which we check for apps using excessive power -- 15 mins.
475    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
476
477    // The minimum sample duration we will allow before deciding we have
478    // enough data on wake locks to start killing things.
479    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
480
481    // The minimum sample duration we will allow before deciding we have
482    // enough data on CPU usage to start killing things.
483    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
484
485    // How long we allow a receiver to run before giving up on it.
486    static final int BROADCAST_FG_TIMEOUT = 10*1000;
487    static final int BROADCAST_BG_TIMEOUT = 60*1000;
488
489    // How long we wait until we timeout on key dispatching.
490    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
491
492    // How long we wait until we timeout on key dispatching during instrumentation.
493    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
494
495    // This is the amount of time an app needs to be running a foreground service before
496    // we will consider it to be doing interaction for usage stats.
497    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
498
499    // Maximum amount of time we will allow to elapse before re-reporting usage stats
500    // interaction with foreground processes.
501    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
502
503    // This is the amount of time we allow an app to settle after it goes into the background,
504    // before we start restricting what it can do.
505    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
506
507    // How long to wait in getAssistContextExtras for the activity and foreground services
508    // to respond with the result.
509    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
510
511    // How long top wait when going through the modern assist (which doesn't need to block
512    // on getting this result before starting to launch its UI).
513    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
514
515    // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result.
516    static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
517
518    // Maximum number of persisted Uri grants a package is allowed
519    static final int MAX_PERSISTED_URI_GRANTS = 128;
520
521    static final int MY_PID = Process.myPid();
522
523    static final String[] EMPTY_STRING_ARRAY = new String[0];
524
525    // How many bytes to write into the dropbox log before truncating
526    static final int DROPBOX_MAX_SIZE = 192 * 1024;
527    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
528    // as one line, but close enough for now.
529    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
530
531    // Access modes for handleIncomingUser.
532    static final int ALLOW_NON_FULL = 0;
533    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
534    static final int ALLOW_FULL_ONLY = 2;
535
536    // Necessary ApplicationInfo flags to mark an app as persistent
537    private static final int PERSISTENT_MASK =
538            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
539
540    // Intent sent when remote bugreport collection has been completed
541    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
542            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
543
544    // Used to indicate that an app transition should be animated.
545    static final boolean ANIMATE = true;
546
547    // Determines whether to take full screen screenshots
548    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
549    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
550
551    /** All system services */
552    SystemServiceManager mSystemServiceManager;
553
554    private Installer mInstaller;
555
556    /** Run all ActivityStacks through this */
557    final ActivityStackSupervisor mStackSupervisor;
558    private final KeyguardController mKeyguardController;
559
560    final ActivityStarter mActivityStarter;
561
562    final TaskChangeNotificationController mTaskChangeNotificationController;
563
564    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
565
566    public IntentFirewall mIntentFirewall;
567
568    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
569    // default action automatically.  Important for devices without direct input
570    // devices.
571    private boolean mShowDialogs = true;
572    private boolean mInVrMode = false;
573
574    // Whether we should use SCHED_FIFO for UI and RenderThreads.
575    private boolean mUseFifoUiScheduling = false;
576
577    BroadcastQueue mFgBroadcastQueue;
578    BroadcastQueue mBgBroadcastQueue;
579    // Convenient for easy iteration over the queues. Foreground is first
580    // so that dispatch of foreground broadcasts gets precedence.
581    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
582
583    BroadcastStats mLastBroadcastStats;
584    BroadcastStats mCurBroadcastStats;
585
586    BroadcastQueue broadcastQueueForIntent(Intent intent) {
587        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
588        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
589                "Broadcast intent " + intent + " on "
590                + (isFg ? "foreground" : "background") + " queue");
591        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
592    }
593
594    /**
595     * The last resumed activity. This is identical to the current resumed activity most
596     * of the time but could be different when we're pausing one activity before we resume
597     * another activity.
598     */
599    private ActivityRecord mLastResumedActivity;
600
601    /**
602     * If non-null, we are tracking the time the user spends in the currently focused app.
603     */
604    private AppTimeTracker mCurAppTimeTracker;
605
606    /**
607     * List of intents that were used to start the most recent tasks.
608     */
609    final RecentTasks mRecentTasks;
610
611    /**
612     * For addAppTask: cached of the last activity component that was added.
613     */
614    ComponentName mLastAddedTaskComponent;
615
616    /**
617     * For addAppTask: cached of the last activity uid that was added.
618     */
619    int mLastAddedTaskUid;
620
621    /**
622     * For addAppTask: cached of the last ActivityInfo that was added.
623     */
624    ActivityInfo mLastAddedTaskActivity;
625
626    /**
627     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
628     */
629    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
630
631    /**
632     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
633     */
634    String mDeviceOwnerName;
635
636    final UserController mUserController;
637
638    final AppErrors mAppErrors;
639
640    public boolean canShowErrorDialogs() {
641        return mShowDialogs && !mSleeping && !mShuttingDown
642                && !mKeyguardController.isKeyguardShowing();
643    }
644
645    private static final class PriorityState {
646        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
647        // the current thread is currently in. When it drops down to zero, we will no longer boost
648        // the thread's priority.
649        private int regionCounter = 0;
650
651        // The thread's previous priority before boosting.
652        private int prevPriority = Integer.MIN_VALUE;
653    }
654
655    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
656        @Override protected PriorityState initialValue() {
657            return new PriorityState();
658        }
659    };
660
661    static void boostPriorityForLockedSection() {
662        int tid = Process.myTid();
663        int prevPriority = Process.getThreadPriority(tid);
664        PriorityState state = sThreadPriorityState.get();
665        if (state.regionCounter == 0 && prevPriority > -2) {
666            state.prevPriority = prevPriority;
667            Process.setThreadPriority(tid, -2);
668        }
669        state.regionCounter++;
670    }
671
672    static void resetPriorityAfterLockedSection() {
673        PriorityState state = sThreadPriorityState.get();
674        state.regionCounter--;
675        if (state.regionCounter == 0 && state.prevPriority > -2) {
676            Process.setThreadPriority(Process.myTid(), state.prevPriority);
677        }
678    }
679
680    public class PendingAssistExtras extends Binder implements Runnable {
681        public final ActivityRecord activity;
682        public final Bundle extras;
683        public final Intent intent;
684        public final String hint;
685        public final IResultReceiver receiver;
686        public final int userHandle;
687        public boolean haveResult = false;
688        public Bundle result = null;
689        public AssistStructure structure = null;
690        public AssistContent content = null;
691        public Bundle receiverExtras;
692        public int flags;
693
694        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
695                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _flags,
696                int _userHandle) {
697            activity = _activity;
698            extras = _extras;
699            intent = _intent;
700            hint = _hint;
701            receiver = _receiver;
702            receiverExtras = _receiverExtras;
703            flags = _flags;
704            userHandle = _userHandle;
705        }
706        @Override
707        public void run() {
708            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
709            synchronized (this) {
710                haveResult = true;
711                notifyAll();
712            }
713            pendingAssistExtrasTimedOut(this);
714        }
715    }
716
717    final ArrayList<PendingAssistExtras> mPendingAssistExtras
718            = new ArrayList<PendingAssistExtras>();
719
720    /**
721     * Process management.
722     */
723    final ProcessList mProcessList = new ProcessList();
724
725    /**
726     * All of the applications we currently have running organized by name.
727     * The keys are strings of the application package name (as
728     * returned by the package manager), and the keys are ApplicationRecord
729     * objects.
730     */
731    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
732
733    /**
734     * Tracking long-term execution of processes to look for abuse and other
735     * bad app behavior.
736     */
737    final ProcessStatsService mProcessStats;
738
739    /**
740     * The currently running isolated processes.
741     */
742    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
743
744    /**
745     * Counter for assigning isolated process uids, to avoid frequently reusing the
746     * same ones.
747     */
748    int mNextIsolatedProcessUid = 0;
749
750    /**
751     * The currently running heavy-weight process, if any.
752     */
753    ProcessRecord mHeavyWeightProcess = null;
754
755    /**
756     * All of the processes we currently have running organized by pid.
757     * The keys are the pid running the application.
758     *
759     * <p>NOTE: This object is protected by its own lock, NOT the global
760     * activity manager lock!
761     */
762    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
763
764    /**
765     * All of the processes that have been forced to be foreground.  The key
766     * is the pid of the caller who requested it (we hold a death
767     * link on it).
768     */
769    abstract class ForegroundToken implements IBinder.DeathRecipient {
770        int pid;
771        IBinder token;
772    }
773    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
774
775    /**
776     * List of records for processes that someone had tried to start before the
777     * system was ready.  We don't start them at that point, but ensure they
778     * are started by the time booting is complete.
779     */
780    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
781
782    /**
783     * List of persistent applications that are in the process
784     * of being started.
785     */
786    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
787
788    /**
789     * Processes that are being forcibly torn down.
790     */
791    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
792
793    /**
794     * List of running applications, sorted by recent usage.
795     * The first entry in the list is the least recently used.
796     */
797    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
798
799    /**
800     * Where in mLruProcesses that the processes hosting activities start.
801     */
802    int mLruProcessActivityStart = 0;
803
804    /**
805     * Where in mLruProcesses that the processes hosting services start.
806     * This is after (lower index) than mLruProcessesActivityStart.
807     */
808    int mLruProcessServiceStart = 0;
809
810    /**
811     * List of processes that should gc as soon as things are idle.
812     */
813    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
814
815    /**
816     * Processes we want to collect PSS data from.
817     */
818    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
819
820    private boolean mBinderTransactionTrackingEnabled = false;
821
822    /**
823     * Last time we requested PSS data of all processes.
824     */
825    long mLastFullPssTime = SystemClock.uptimeMillis();
826
827    /**
828     * If set, the next time we collect PSS data we should do a full collection
829     * with data from native processes and the kernel.
830     */
831    boolean mFullPssPending = false;
832
833    /**
834     * This is the process holding what we currently consider to be
835     * the "home" activity.
836     */
837    ProcessRecord mHomeProcess;
838
839    /**
840     * This is the process holding the activity the user last visited that
841     * is in a different process from the one they are currently in.
842     */
843    ProcessRecord mPreviousProcess;
844
845    /**
846     * The time at which the previous process was last visible.
847     */
848    long mPreviousProcessVisibleTime;
849
850    /**
851     * Track all uids that have actively running processes.
852     */
853    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
854
855    /**
856     * This is for verifying the UID report flow.
857     */
858    static final boolean VALIDATE_UID_STATES = true;
859    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
860
861    /**
862     * Packages that the user has asked to have run in screen size
863     * compatibility mode instead of filling the screen.
864     */
865    final CompatModePackages mCompatModePackages;
866
867    /**
868     * Set of IntentSenderRecord objects that are currently active.
869     */
870    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
871            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
872
873    /**
874     * Fingerprints (hashCode()) of stack traces that we've
875     * already logged DropBox entries for.  Guarded by itself.  If
876     * something (rogue user app) forces this over
877     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
878     */
879    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
880    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
881
882    /**
883     * Strict Mode background batched logging state.
884     *
885     * The string buffer is guarded by itself, and its lock is also
886     * used to determine if another batched write is already
887     * in-flight.
888     */
889    private final StringBuilder mStrictModeBuffer = new StringBuilder();
890
891    /**
892     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
893     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
894     */
895    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
896
897    /**
898     * Resolver for broadcast intents to registered receivers.
899     * Holds BroadcastFilter (subclass of IntentFilter).
900     */
901    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
902            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
903        @Override
904        protected boolean allowFilterResult(
905                BroadcastFilter filter, List<BroadcastFilter> dest) {
906            IBinder target = filter.receiverList.receiver.asBinder();
907            for (int i = dest.size() - 1; i >= 0; i--) {
908                if (dest.get(i).receiverList.receiver.asBinder() == target) {
909                    return false;
910                }
911            }
912            return true;
913        }
914
915        @Override
916        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
917            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
918                    || userId == filter.owningUserId) {
919                return super.newResult(filter, match, userId);
920            }
921            return null;
922        }
923
924        @Override
925        protected BroadcastFilter[] newArray(int size) {
926            return new BroadcastFilter[size];
927        }
928
929        @Override
930        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
931            return packageName.equals(filter.packageName);
932        }
933    };
934
935    /**
936     * State of all active sticky broadcasts per user.  Keys are the action of the
937     * sticky Intent, values are an ArrayList of all broadcasted intents with
938     * that action (which should usually be one).  The SparseArray is keyed
939     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
940     * for stickies that are sent to all users.
941     */
942    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
943            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
944
945    final ActiveServices mServices;
946
947    final static class Association {
948        final int mSourceUid;
949        final String mSourceProcess;
950        final int mTargetUid;
951        final ComponentName mTargetComponent;
952        final String mTargetProcess;
953
954        int mCount;
955        long mTime;
956
957        int mNesting;
958        long mStartTime;
959
960        // states of the source process when the bind occurred.
961        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
962        long mLastStateUptime;
963        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
964                - ActivityManager.MIN_PROCESS_STATE+1];
965
966        Association(int sourceUid, String sourceProcess, int targetUid,
967                ComponentName targetComponent, String targetProcess) {
968            mSourceUid = sourceUid;
969            mSourceProcess = sourceProcess;
970            mTargetUid = targetUid;
971            mTargetComponent = targetComponent;
972            mTargetProcess = targetProcess;
973        }
974    }
975
976    /**
977     * When service association tracking is enabled, this is all of the associations we
978     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
979     * -> association data.
980     */
981    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
982            mAssociations = new SparseArray<>();
983    boolean mTrackingAssociations;
984
985    /**
986     * Backup/restore process management
987     */
988    String mBackupAppName = null;
989    BackupRecord mBackupTarget = null;
990
991    final ProviderMap mProviderMap;
992
993    /**
994     * List of content providers who have clients waiting for them.  The
995     * application is currently being launched and the provider will be
996     * removed from this list once it is published.
997     */
998    final ArrayList<ContentProviderRecord> mLaunchingProviders
999            = new ArrayList<ContentProviderRecord>();
1000
1001    /**
1002     * File storing persisted {@link #mGrantedUriPermissions}.
1003     */
1004    private final AtomicFile mGrantFile;
1005
1006    /** XML constants used in {@link #mGrantFile} */
1007    private static final String TAG_URI_GRANTS = "uri-grants";
1008    private static final String TAG_URI_GRANT = "uri-grant";
1009    private static final String ATTR_USER_HANDLE = "userHandle";
1010    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1011    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1012    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1013    private static final String ATTR_TARGET_PKG = "targetPkg";
1014    private static final String ATTR_URI = "uri";
1015    private static final String ATTR_MODE_FLAGS = "modeFlags";
1016    private static final String ATTR_CREATED_TIME = "createdTime";
1017    private static final String ATTR_PREFIX = "prefix";
1018
1019    /**
1020     * Global set of specific {@link Uri} permissions that have been granted.
1021     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1022     * to {@link UriPermission#uri} to {@link UriPermission}.
1023     */
1024    @GuardedBy("this")
1025    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1026            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1027
1028    public static class GrantUri {
1029        public final int sourceUserId;
1030        public final Uri uri;
1031        public boolean prefix;
1032
1033        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1034            this.sourceUserId = sourceUserId;
1035            this.uri = uri;
1036            this.prefix = prefix;
1037        }
1038
1039        @Override
1040        public int hashCode() {
1041            int hashCode = 1;
1042            hashCode = 31 * hashCode + sourceUserId;
1043            hashCode = 31 * hashCode + uri.hashCode();
1044            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1045            return hashCode;
1046        }
1047
1048        @Override
1049        public boolean equals(Object o) {
1050            if (o instanceof GrantUri) {
1051                GrantUri other = (GrantUri) o;
1052                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1053                        && prefix == other.prefix;
1054            }
1055            return false;
1056        }
1057
1058        @Override
1059        public String toString() {
1060            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1061            if (prefix) result += " [prefix]";
1062            return result;
1063        }
1064
1065        public String toSafeString() {
1066            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1067            if (prefix) result += " [prefix]";
1068            return result;
1069        }
1070
1071        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1072            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1073                    ContentProvider.getUriWithoutUserId(uri), false);
1074        }
1075    }
1076
1077    CoreSettingsObserver mCoreSettingsObserver;
1078
1079    FontScaleSettingObserver mFontScaleSettingObserver;
1080
1081    private final class FontScaleSettingObserver extends ContentObserver {
1082        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1083
1084        public FontScaleSettingObserver() {
1085            super(mHandler);
1086            ContentResolver resolver = mContext.getContentResolver();
1087            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1088        }
1089
1090        @Override
1091        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1092            if (mFontScaleUri.equals(uri)) {
1093                updateFontScaleIfNeeded(userId);
1094            }
1095        }
1096    }
1097
1098    /**
1099     * Thread-local storage used to carry caller permissions over through
1100     * indirect content-provider access.
1101     */
1102    private class Identity {
1103        public final IBinder token;
1104        public final int pid;
1105        public final int uid;
1106
1107        Identity(IBinder _token, int _pid, int _uid) {
1108            token = _token;
1109            pid = _pid;
1110            uid = _uid;
1111        }
1112    }
1113
1114    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1115
1116    /**
1117     * All information we have collected about the runtime performance of
1118     * any user id that can impact battery performance.
1119     */
1120    final BatteryStatsService mBatteryStatsService;
1121
1122    /**
1123     * Information about component usage
1124     */
1125    UsageStatsManagerInternal mUsageStatsService;
1126
1127    /**
1128     * Access to DeviceIdleController service.
1129     */
1130    DeviceIdleController.LocalService mLocalDeviceIdleController;
1131
1132    /**
1133     * Information about and control over application operations
1134     */
1135    final AppOpsService mAppOpsService;
1136
1137    /** Current sequencing integer of the configuration, for skipping old configurations. */
1138    private int mConfigurationSeq;
1139
1140    /**
1141     * Temp object used when global and/or display override configuration is updated. It is also
1142     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1143     * anyone...
1144     */
1145    private Configuration mTempConfig = new Configuration();
1146
1147    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1148            new UpdateConfigurationResult();
1149    private static final class UpdateConfigurationResult {
1150        // Configuration changes that were updated.
1151        int changes;
1152        // If the activity was relaunched to match the new configuration.
1153        boolean activityRelaunched;
1154
1155        void reset() {
1156            changes = 0;
1157            activityRelaunched = false;
1158        }
1159    }
1160
1161    boolean mSuppressResizeConfigChanges;
1162
1163    /**
1164     * Hardware-reported OpenGLES version.
1165     */
1166    final int GL_ES_VERSION;
1167
1168    /**
1169     * List of initialization arguments to pass to all processes when binding applications to them.
1170     * For example, references to the commonly used services.
1171     */
1172    HashMap<String, IBinder> mAppBindArgs;
1173    HashMap<String, IBinder> mIsolatedAppBindArgs;
1174
1175    /**
1176     * Temporary to avoid allocations.  Protected by main lock.
1177     */
1178    final StringBuilder mStringBuilder = new StringBuilder(256);
1179
1180    /**
1181     * Used to control how we initialize the service.
1182     */
1183    ComponentName mTopComponent;
1184    String mTopAction = Intent.ACTION_MAIN;
1185    String mTopData;
1186
1187    volatile boolean mProcessesReady = false;
1188    volatile boolean mSystemReady = false;
1189    volatile boolean mOnBattery = false;
1190    volatile int mFactoryTest;
1191
1192    @GuardedBy("this") boolean mBooting = false;
1193    @GuardedBy("this") boolean mCallFinishBooting = false;
1194    @GuardedBy("this") boolean mBootAnimationComplete = false;
1195    @GuardedBy("this") boolean mLaunchWarningShown = false;
1196    @GuardedBy("this") boolean mCheckedForSetup = false;
1197
1198    Context mContext;
1199
1200    /**
1201     * The time at which we will allow normal application switches again,
1202     * after a call to {@link #stopAppSwitches()}.
1203     */
1204    long mAppSwitchesAllowedTime;
1205
1206    /**
1207     * This is set to true after the first switch after mAppSwitchesAllowedTime
1208     * is set; any switches after that will clear the time.
1209     */
1210    boolean mDidAppSwitch;
1211
1212    /**
1213     * Last time (in realtime) at which we checked for power usage.
1214     */
1215    long mLastPowerCheckRealtime;
1216
1217    /**
1218     * Last time (in uptime) at which we checked for power usage.
1219     */
1220    long mLastPowerCheckUptime;
1221
1222    /**
1223     * Set while we are wanting to sleep, to prevent any
1224     * activities from being started/resumed.
1225     *
1226     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1227     *
1228     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1229     * while in the sleep state until there is a pending transition out of sleep, in which case
1230     * mSleeping is set to false, and remains false while awake.
1231     *
1232     * Whether mSleeping can quickly toggled between true/false without the device actually
1233     * display changing states is undefined.
1234     */
1235    private boolean mSleeping = false;
1236
1237    /**
1238     * The process state used for processes that are running the top activities.
1239     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1240     */
1241    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1242
1243    /**
1244     * Set while we are running a voice interaction.  This overrides
1245     * sleeping while it is active.
1246     */
1247    private IVoiceInteractionSession mRunningVoice;
1248
1249    /**
1250     * For some direct access we need to power manager.
1251     */
1252    PowerManagerInternal mLocalPowerManager;
1253
1254    /**
1255     * We want to hold a wake lock while running a voice interaction session, since
1256     * this may happen with the screen off and we need to keep the CPU running to
1257     * be able to continue to interact with the user.
1258     */
1259    PowerManager.WakeLock mVoiceWakeLock;
1260
1261    /**
1262     * State of external calls telling us if the device is awake or asleep.
1263     */
1264    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1265
1266    /**
1267     * A list of tokens that cause the top activity to be put to sleep.
1268     * They are used by components that may hide and block interaction with underlying
1269     * activities.
1270     */
1271    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1272
1273    /**
1274     * Set if we are shutting down the system, similar to sleeping.
1275     */
1276    boolean mShuttingDown = false;
1277
1278    /**
1279     * Current sequence id for oom_adj computation traversal.
1280     */
1281    int mAdjSeq = 0;
1282
1283    /**
1284     * Current sequence id for process LRU updating.
1285     */
1286    int mLruSeq = 0;
1287
1288    /**
1289     * Keep track of the non-cached/empty process we last found, to help
1290     * determine how to distribute cached/empty processes next time.
1291     */
1292    int mNumNonCachedProcs = 0;
1293
1294    /**
1295     * Keep track of the number of cached hidden procs, to balance oom adj
1296     * distribution between those and empty procs.
1297     */
1298    int mNumCachedHiddenProcs = 0;
1299
1300    /**
1301     * Keep track of the number of service processes we last found, to
1302     * determine on the next iteration which should be B services.
1303     */
1304    int mNumServiceProcs = 0;
1305    int mNewNumAServiceProcs = 0;
1306    int mNewNumServiceProcs = 0;
1307
1308    /**
1309     * Allow the current computed overall memory level of the system to go down?
1310     * This is set to false when we are killing processes for reasons other than
1311     * memory management, so that the now smaller process list will not be taken as
1312     * an indication that memory is tighter.
1313     */
1314    boolean mAllowLowerMemLevel = false;
1315
1316    /**
1317     * The last computed memory level, for holding when we are in a state that
1318     * processes are going away for other reasons.
1319     */
1320    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1321
1322    /**
1323     * The last total number of process we have, to determine if changes actually look
1324     * like a shrinking number of process due to lower RAM.
1325     */
1326    int mLastNumProcesses;
1327
1328    /**
1329     * The uptime of the last time we performed idle maintenance.
1330     */
1331    long mLastIdleTime = SystemClock.uptimeMillis();
1332
1333    /**
1334     * Total time spent with RAM that has been added in the past since the last idle time.
1335     */
1336    long mLowRamTimeSinceLastIdle = 0;
1337
1338    /**
1339     * If RAM is currently low, when that horrible situation started.
1340     */
1341    long mLowRamStartTime = 0;
1342
1343    /**
1344     * For reporting to battery stats the current top application.
1345     */
1346    private String mCurResumedPackage = null;
1347    private int mCurResumedUid = -1;
1348
1349    /**
1350     * For reporting to battery stats the apps currently running foreground
1351     * service.  The ProcessMap is package/uid tuples; each of these contain
1352     * an array of the currently foreground processes.
1353     */
1354    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1355            = new ProcessMap<ArrayList<ProcessRecord>>();
1356
1357    /**
1358     * This is set if we had to do a delayed dexopt of an app before launching
1359     * it, to increase the ANR timeouts in that case.
1360     */
1361    boolean mDidDexOpt;
1362
1363    /**
1364     * Set if the systemServer made a call to enterSafeMode.
1365     */
1366    boolean mSafeMode;
1367
1368    /**
1369     * If true, we are running under a test environment so will sample PSS from processes
1370     * much more rapidly to try to collect better data when the tests are rapidly
1371     * running through apps.
1372     */
1373    boolean mTestPssMode = false;
1374
1375    String mDebugApp = null;
1376    boolean mWaitForDebugger = false;
1377    boolean mDebugTransient = false;
1378    String mOrigDebugApp = null;
1379    boolean mOrigWaitForDebugger = false;
1380    boolean mAlwaysFinishActivities = false;
1381    boolean mForceResizableActivities;
1382    boolean mSupportsMultiWindow;
1383    boolean mSupportsSplitScreenMultiWindow;
1384    boolean mSupportsFreeformWindowManagement;
1385    boolean mSupportsPictureInPicture;
1386    boolean mSupportsLeanbackOnly;
1387    IActivityController mController = null;
1388    boolean mControllerIsAMonkey = false;
1389    String mProfileApp = null;
1390    ProcessRecord mProfileProc = null;
1391    String mProfileFile;
1392    ParcelFileDescriptor mProfileFd;
1393    int mSamplingInterval = 0;
1394    boolean mAutoStopProfiler = false;
1395    int mProfileType = 0;
1396    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1397    String mMemWatchDumpProcName;
1398    String mMemWatchDumpFile;
1399    int mMemWatchDumpPid;
1400    int mMemWatchDumpUid;
1401    String mTrackAllocationApp = null;
1402    String mNativeDebuggingApp = null;
1403
1404    final long[] mTmpLong = new long[2];
1405
1406    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1407
1408    static final class ProcessChangeItem {
1409        static final int CHANGE_ACTIVITIES = 1<<0;
1410        static final int CHANGE_PROCESS_STATE = 1<<1;
1411        int changes;
1412        int uid;
1413        int pid;
1414        int processState;
1415        boolean foregroundActivities;
1416    }
1417
1418    static final class UidObserverRegistration {
1419        final int uid;
1420        final String pkg;
1421        final int which;
1422        final int cutpoint;
1423
1424        final SparseIntArray lastProcStates;
1425
1426        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1427            uid = _uid;
1428            pkg = _pkg;
1429            which = _which;
1430            cutpoint = _cutpoint;
1431            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1432                lastProcStates = new SparseIntArray();
1433            } else {
1434                lastProcStates = null;
1435            }
1436        }
1437    }
1438
1439    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1440    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1441
1442    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1443    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1444
1445    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1446    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1447
1448    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1449    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1450
1451    /**
1452     * Runtime CPU use collection thread.  This object's lock is used to
1453     * perform synchronization with the thread (notifying it to run).
1454     */
1455    final Thread mProcessCpuThread;
1456
1457    /**
1458     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1459     * Must acquire this object's lock when accessing it.
1460     * NOTE: this lock will be held while doing long operations (trawling
1461     * through all processes in /proc), so it should never be acquired by
1462     * any critical paths such as when holding the main activity manager lock.
1463     */
1464    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1465            MONITOR_THREAD_CPU_USAGE);
1466    final AtomicLong mLastCpuTime = new AtomicLong(0);
1467    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1468
1469    long mLastWriteTime = 0;
1470
1471    /**
1472     * Used to retain an update lock when the foreground activity is in
1473     * immersive mode.
1474     */
1475    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1476
1477    /**
1478     * Set to true after the system has finished booting.
1479     */
1480    boolean mBooted = false;
1481
1482    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1483    int mProcessLimitOverride = -1;
1484
1485    WindowManagerService mWindowManager;
1486    final ActivityThread mSystemThread;
1487
1488    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1489        final ProcessRecord mApp;
1490        final int mPid;
1491        final IApplicationThread mAppThread;
1492
1493        AppDeathRecipient(ProcessRecord app, int pid,
1494                IApplicationThread thread) {
1495            if (DEBUG_ALL) Slog.v(
1496                TAG, "New death recipient " + this
1497                + " for thread " + thread.asBinder());
1498            mApp = app;
1499            mPid = pid;
1500            mAppThread = thread;
1501        }
1502
1503        @Override
1504        public void binderDied() {
1505            if (DEBUG_ALL) Slog.v(
1506                TAG, "Death received in " + this
1507                + " for thread " + mAppThread.asBinder());
1508            synchronized(ActivityManagerService.this) {
1509                appDiedLocked(mApp, mPid, mAppThread, true);
1510            }
1511        }
1512    }
1513
1514    static final int SHOW_ERROR_UI_MSG = 1;
1515    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1516    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1517    static final int UPDATE_CONFIGURATION_MSG = 4;
1518    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1519    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1520    static final int SERVICE_TIMEOUT_MSG = 12;
1521    static final int UPDATE_TIME_ZONE = 13;
1522    static final int SHOW_UID_ERROR_UI_MSG = 14;
1523    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1524    static final int PROC_START_TIMEOUT_MSG = 20;
1525    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1526    static final int KILL_APPLICATION_MSG = 22;
1527    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1528    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1529    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1530    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1531    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1532    static final int CLEAR_DNS_CACHE_MSG = 28;
1533    static final int UPDATE_HTTP_PROXY_MSG = 29;
1534    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1535    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1536    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1537    static final int REPORT_MEM_USAGE_MSG = 33;
1538    static final int REPORT_USER_SWITCH_MSG = 34;
1539    static final int CONTINUE_USER_SWITCH_MSG = 35;
1540    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1541    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1542    static final int PERSIST_URI_GRANTS_MSG = 38;
1543    static final int REQUEST_ALL_PSS_MSG = 39;
1544    static final int START_PROFILES_MSG = 40;
1545    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1546    static final int SYSTEM_USER_START_MSG = 42;
1547    static final int SYSTEM_USER_CURRENT_MSG = 43;
1548    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1549    static final int FINISH_BOOTING_MSG = 45;
1550    static final int START_USER_SWITCH_UI_MSG = 46;
1551    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1552    static final int DISMISS_DIALOG_UI_MSG = 48;
1553    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1554    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1555    static final int DELETE_DUMPHEAP_MSG = 51;
1556    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1557    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1558    static final int REPORT_TIME_TRACKER_MSG = 54;
1559    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1560    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1561    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1562    static final int IDLE_UIDS_MSG = 58;
1563    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1564    static final int LOG_STACK_STATE = 60;
1565    static final int VR_MODE_CHANGE_MSG = 61;
1566    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1567    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1568    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1569    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1570    static final int START_USER_SWITCH_FG_MSG = 712;
1571
1572    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1573    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1574    static final int FIRST_COMPAT_MODE_MSG = 300;
1575    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1576
1577    static ServiceThread sKillThread = null;
1578    static KillHandler sKillHandler = null;
1579
1580    CompatModeDialog mCompatModeDialog;
1581    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1582    long mLastMemUsageReportTime = 0;
1583
1584    /**
1585     * Flag whether the current user is a "monkey", i.e. whether
1586     * the UI is driven by a UI automation tool.
1587     */
1588    private boolean mUserIsMonkey;
1589
1590    /** Flag whether the device has a Recents UI */
1591    boolean mHasRecents;
1592
1593    /** The dimensions of the thumbnails in the Recents UI. */
1594    int mThumbnailWidth;
1595    int mThumbnailHeight;
1596    float mFullscreenThumbnailScale;
1597
1598    /** The aspect ratio bounds of the PIP. */
1599    float mMinPipAspectRatio;
1600    float mMaxPipAspectRatio;
1601
1602    final ServiceThread mHandlerThread;
1603    final MainHandler mHandler;
1604    final UiHandler mUiHandler;
1605
1606    PackageManagerInternal mPackageManagerInt;
1607
1608    // VoiceInteraction session ID that changes for each new request except when
1609    // being called for multiwindow assist in a single session.
1610    private int mViSessionId = 1000;
1611
1612    final boolean mPermissionReviewRequired;
1613
1614    /**
1615     * Current global configuration information. Contains general settings for the entire system,
1616     * also corresponds to the merged configuration of the default display.
1617     */
1618    Configuration getGlobalConfiguration() {
1619        return mStackSupervisor.getConfiguration();
1620    }
1621
1622    final class KillHandler extends Handler {
1623        static final int KILL_PROCESS_GROUP_MSG = 4000;
1624
1625        public KillHandler(Looper looper) {
1626            super(looper, null, true);
1627        }
1628
1629        @Override
1630        public void handleMessage(Message msg) {
1631            switch (msg.what) {
1632                case KILL_PROCESS_GROUP_MSG:
1633                {
1634                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1635                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1636                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1637                }
1638                break;
1639
1640                default:
1641                    super.handleMessage(msg);
1642            }
1643        }
1644    }
1645
1646    final class UiHandler extends Handler {
1647        public UiHandler() {
1648            super(com.android.server.UiThread.get().getLooper(), null, true);
1649        }
1650
1651        @Override
1652        public void handleMessage(Message msg) {
1653            switch (msg.what) {
1654            case SHOW_ERROR_UI_MSG: {
1655                mAppErrors.handleShowAppErrorUi(msg);
1656                ensureBootCompleted();
1657            } break;
1658            case SHOW_NOT_RESPONDING_UI_MSG: {
1659                mAppErrors.handleShowAnrUi(msg);
1660                ensureBootCompleted();
1661            } break;
1662            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1663                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1664                synchronized (ActivityManagerService.this) {
1665                    ProcessRecord proc = (ProcessRecord) data.get("app");
1666                    if (proc == null) {
1667                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1668                        break;
1669                    }
1670                    if (proc.crashDialog != null) {
1671                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1672                        return;
1673                    }
1674                    AppErrorResult res = (AppErrorResult) data.get("result");
1675                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1676                        Dialog d = new StrictModeViolationDialog(mContext,
1677                                ActivityManagerService.this, res, proc);
1678                        d.show();
1679                        proc.crashDialog = d;
1680                    } else {
1681                        // The device is asleep, so just pretend that the user
1682                        // saw a crash dialog and hit "force quit".
1683                        res.set(0);
1684                    }
1685                }
1686                ensureBootCompleted();
1687            } break;
1688            case SHOW_FACTORY_ERROR_UI_MSG: {
1689                Dialog d = new FactoryErrorDialog(
1690                    mContext, msg.getData().getCharSequence("msg"));
1691                d.show();
1692                ensureBootCompleted();
1693            } break;
1694            case WAIT_FOR_DEBUGGER_UI_MSG: {
1695                synchronized (ActivityManagerService.this) {
1696                    ProcessRecord app = (ProcessRecord)msg.obj;
1697                    if (msg.arg1 != 0) {
1698                        if (!app.waitedForDebugger) {
1699                            Dialog d = new AppWaitingForDebuggerDialog(
1700                                    ActivityManagerService.this,
1701                                    mContext, app);
1702                            app.waitDialog = d;
1703                            app.waitedForDebugger = true;
1704                            d.show();
1705                        }
1706                    } else {
1707                        if (app.waitDialog != null) {
1708                            app.waitDialog.dismiss();
1709                            app.waitDialog = null;
1710                        }
1711                    }
1712                }
1713            } break;
1714            case SHOW_UID_ERROR_UI_MSG: {
1715                if (mShowDialogs) {
1716                    AlertDialog d = new BaseErrorDialog(mContext);
1717                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1718                    d.setCancelable(false);
1719                    d.setTitle(mContext.getText(R.string.android_system_label));
1720                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1721                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1722                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1723                    d.show();
1724                }
1725            } break;
1726            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1727                if (mShowDialogs) {
1728                    AlertDialog d = new BaseErrorDialog(mContext);
1729                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1730                    d.setCancelable(false);
1731                    d.setTitle(mContext.getText(R.string.android_system_label));
1732                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1733                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1734                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1735                    d.show();
1736                }
1737            } break;
1738            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1739                synchronized (ActivityManagerService.this) {
1740                    ActivityRecord ar = (ActivityRecord) msg.obj;
1741                    if (mCompatModeDialog != null) {
1742                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1743                                ar.info.applicationInfo.packageName)) {
1744                            return;
1745                        }
1746                        mCompatModeDialog.dismiss();
1747                        mCompatModeDialog = null;
1748                    }
1749                    if (ar != null && false) {
1750                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1751                                ar.packageName)) {
1752                            int mode = mCompatModePackages.computeCompatModeLocked(
1753                                    ar.info.applicationInfo);
1754                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1755                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1756                                mCompatModeDialog = new CompatModeDialog(
1757                                        ActivityManagerService.this, mContext,
1758                                        ar.info.applicationInfo);
1759                                mCompatModeDialog.show();
1760                            }
1761                        }
1762                    }
1763                }
1764                break;
1765            }
1766            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1767                synchronized (ActivityManagerService.this) {
1768                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1769                    if (mUnsupportedDisplaySizeDialog != null) {
1770                        mUnsupportedDisplaySizeDialog.dismiss();
1771                        mUnsupportedDisplaySizeDialog = null;
1772                    }
1773                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1774                            ar.packageName)) {
1775                        // TODO(multi-display): Show dialog on appropriate display.
1776                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1777                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1778                        mUnsupportedDisplaySizeDialog.show();
1779                    }
1780                }
1781                break;
1782            }
1783            case START_USER_SWITCH_UI_MSG: {
1784                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1785                break;
1786            }
1787            case DISMISS_DIALOG_UI_MSG: {
1788                final Dialog d = (Dialog) msg.obj;
1789                d.dismiss();
1790                break;
1791            }
1792            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1793                dispatchProcessesChanged();
1794                break;
1795            }
1796            case DISPATCH_PROCESS_DIED_UI_MSG: {
1797                final int pid = msg.arg1;
1798                final int uid = msg.arg2;
1799                dispatchProcessDied(pid, uid);
1800                break;
1801            }
1802            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1803                dispatchUidsChanged();
1804            } break;
1805            }
1806        }
1807    }
1808
1809    final class MainHandler extends Handler {
1810        public MainHandler(Looper looper) {
1811            super(looper, null, true);
1812        }
1813
1814        @Override
1815        public void handleMessage(Message msg) {
1816            switch (msg.what) {
1817            case UPDATE_CONFIGURATION_MSG: {
1818                final ContentResolver resolver = mContext.getContentResolver();
1819                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1820                        msg.arg1);
1821            } break;
1822            case GC_BACKGROUND_PROCESSES_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    performAppGcsIfAppropriateLocked();
1825                }
1826            } break;
1827            case SERVICE_TIMEOUT_MSG: {
1828                if (mDidDexOpt) {
1829                    mDidDexOpt = false;
1830                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1831                    nmsg.obj = msg.obj;
1832                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1833                    return;
1834                }
1835                mServices.serviceTimeout((ProcessRecord)msg.obj);
1836            } break;
1837            case UPDATE_TIME_ZONE: {
1838                synchronized (ActivityManagerService.this) {
1839                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1840                        ProcessRecord r = mLruProcesses.get(i);
1841                        if (r.thread != null) {
1842                            try {
1843                                r.thread.updateTimeZone();
1844                            } catch (RemoteException ex) {
1845                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1846                            }
1847                        }
1848                    }
1849                }
1850            } break;
1851            case CLEAR_DNS_CACHE_MSG: {
1852                synchronized (ActivityManagerService.this) {
1853                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1854                        ProcessRecord r = mLruProcesses.get(i);
1855                        if (r.thread != null) {
1856                            try {
1857                                r.thread.clearDnsCache();
1858                            } catch (RemoteException ex) {
1859                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1860                            }
1861                        }
1862                    }
1863                }
1864            } break;
1865            case UPDATE_HTTP_PROXY_MSG: {
1866                ProxyInfo proxy = (ProxyInfo)msg.obj;
1867                String host = "";
1868                String port = "";
1869                String exclList = "";
1870                Uri pacFileUrl = Uri.EMPTY;
1871                if (proxy != null) {
1872                    host = proxy.getHost();
1873                    port = Integer.toString(proxy.getPort());
1874                    exclList = proxy.getExclusionListAsString();
1875                    pacFileUrl = proxy.getPacFileUrl();
1876                }
1877                synchronized (ActivityManagerService.this) {
1878                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1879                        ProcessRecord r = mLruProcesses.get(i);
1880                        if (r.thread != null) {
1881                            try {
1882                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1883                            } catch (RemoteException ex) {
1884                                Slog.w(TAG, "Failed to update http proxy for: " +
1885                                        r.info.processName);
1886                            }
1887                        }
1888                    }
1889                }
1890            } break;
1891            case PROC_START_TIMEOUT_MSG: {
1892                if (mDidDexOpt) {
1893                    mDidDexOpt = false;
1894                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1895                    nmsg.obj = msg.obj;
1896                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1897                    return;
1898                }
1899                ProcessRecord app = (ProcessRecord)msg.obj;
1900                synchronized (ActivityManagerService.this) {
1901                    processStartTimedOutLocked(app);
1902                }
1903            } break;
1904            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1905                ProcessRecord app = (ProcessRecord)msg.obj;
1906                synchronized (ActivityManagerService.this) {
1907                    processContentProviderPublishTimedOutLocked(app);
1908                }
1909            } break;
1910            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1911                synchronized (ActivityManagerService.this) {
1912                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1913                }
1914            } break;
1915            case KILL_APPLICATION_MSG: {
1916                synchronized (ActivityManagerService.this) {
1917                    final int appId = msg.arg1;
1918                    final int userId = msg.arg2;
1919                    Bundle bundle = (Bundle)msg.obj;
1920                    String pkg = bundle.getString("pkg");
1921                    String reason = bundle.getString("reason");
1922                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1923                            false, userId, reason);
1924                }
1925            } break;
1926            case FINALIZE_PENDING_INTENT_MSG: {
1927                ((PendingIntentRecord)msg.obj).completeFinalize();
1928            } break;
1929            case POST_HEAVY_NOTIFICATION_MSG: {
1930                INotificationManager inm = NotificationManager.getService();
1931                if (inm == null) {
1932                    return;
1933                }
1934
1935                ActivityRecord root = (ActivityRecord)msg.obj;
1936                ProcessRecord process = root.app;
1937                if (process == null) {
1938                    return;
1939                }
1940
1941                try {
1942                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1943                    String text = mContext.getString(R.string.heavy_weight_notification,
1944                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1945                    Notification notification = new Notification.Builder(context)
1946                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1947                            .setWhen(0)
1948                            .setOngoing(true)
1949                            .setTicker(text)
1950                            .setColor(mContext.getColor(
1951                                    com.android.internal.R.color.system_notification_accent_color))
1952                            .setContentTitle(text)
1953                            .setContentText(
1954                                    mContext.getText(R.string.heavy_weight_notification_detail))
1955                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1956                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1957                                    new UserHandle(root.userId)))
1958                            .build();
1959                    try {
1960                        int[] outId = new int[1];
1961                        inm.enqueueNotificationWithTag("android", "android", null,
1962                                R.string.heavy_weight_notification,
1963                                notification, outId, root.userId);
1964                    } catch (RuntimeException e) {
1965                        Slog.w(ActivityManagerService.TAG,
1966                                "Error showing notification for heavy-weight app", e);
1967                    } catch (RemoteException e) {
1968                    }
1969                } catch (NameNotFoundException e) {
1970                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1971                }
1972            } break;
1973            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1974                INotificationManager inm = NotificationManager.getService();
1975                if (inm == null) {
1976                    return;
1977                }
1978                try {
1979                    inm.cancelNotificationWithTag("android", null,
1980                            R.string.heavy_weight_notification,  msg.arg1);
1981                } catch (RuntimeException e) {
1982                    Slog.w(ActivityManagerService.TAG,
1983                            "Error canceling notification for service", e);
1984                } catch (RemoteException e) {
1985                }
1986            } break;
1987            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1988                synchronized (ActivityManagerService.this) {
1989                    checkExcessivePowerUsageLocked(true);
1990                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1991                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1992                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1993                }
1994            } break;
1995            case REPORT_MEM_USAGE_MSG: {
1996                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1997                Thread thread = new Thread() {
1998                    @Override public void run() {
1999                        reportMemUsage(memInfos);
2000                    }
2001                };
2002                thread.start();
2003                break;
2004            }
2005            case START_USER_SWITCH_FG_MSG: {
2006                mUserController.startUserInForeground(msg.arg1);
2007                break;
2008            }
2009            case REPORT_USER_SWITCH_MSG: {
2010                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2011                break;
2012            }
2013            case CONTINUE_USER_SWITCH_MSG: {
2014                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2015                break;
2016            }
2017            case USER_SWITCH_TIMEOUT_MSG: {
2018                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2019                break;
2020            }
2021            case IMMERSIVE_MODE_LOCK_MSG: {
2022                final boolean nextState = (msg.arg1 != 0);
2023                if (mUpdateLock.isHeld() != nextState) {
2024                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2025                            "Applying new update lock state '" + nextState
2026                            + "' for " + (ActivityRecord)msg.obj);
2027                    if (nextState) {
2028                        mUpdateLock.acquire();
2029                    } else {
2030                        mUpdateLock.release();
2031                    }
2032                }
2033                break;
2034            }
2035            case PERSIST_URI_GRANTS_MSG: {
2036                writeGrantedUriPermissions();
2037                break;
2038            }
2039            case REQUEST_ALL_PSS_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2042                }
2043                break;
2044            }
2045            case START_PROFILES_MSG: {
2046                synchronized (ActivityManagerService.this) {
2047                    mUserController.startProfilesLocked();
2048                }
2049                break;
2050            }
2051            case UPDATE_TIME_PREFERENCE_MSG: {
2052                // The user's time format preference might have changed.
2053                // For convenience we re-use the Intent extra values.
2054                synchronized (ActivityManagerService.this) {
2055                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2056                        ProcessRecord r = mLruProcesses.get(i);
2057                        if (r.thread != null) {
2058                            try {
2059                                r.thread.updateTimePrefs(msg.arg1);
2060                            } catch (RemoteException ex) {
2061                                Slog.w(TAG, "Failed to update preferences for: "
2062                                        + r.info.processName);
2063                            }
2064                        }
2065                    }
2066                }
2067                break;
2068            }
2069            case SYSTEM_USER_START_MSG: {
2070                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2071                        Integer.toString(msg.arg1), msg.arg1);
2072                mSystemServiceManager.startUser(msg.arg1);
2073                break;
2074            }
2075            case SYSTEM_USER_UNLOCK_MSG: {
2076                final int userId = msg.arg1;
2077                mSystemServiceManager.unlockUser(userId);
2078                synchronized (ActivityManagerService.this) {
2079                    mRecentTasks.loadUserRecentsLocked(userId);
2080                }
2081                if (userId == UserHandle.USER_SYSTEM) {
2082                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2083                }
2084                installEncryptionUnawareProviders(userId);
2085                mUserController.finishUserUnlocked((UserState) msg.obj);
2086                break;
2087            }
2088            case SYSTEM_USER_CURRENT_MSG: {
2089                mBatteryStatsService.noteEvent(
2090                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2091                        Integer.toString(msg.arg2), msg.arg2);
2092                mBatteryStatsService.noteEvent(
2093                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2094                        Integer.toString(msg.arg1), msg.arg1);
2095                mSystemServiceManager.switchUser(msg.arg1);
2096                break;
2097            }
2098            case ENTER_ANIMATION_COMPLETE_MSG: {
2099                synchronized (ActivityManagerService.this) {
2100                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2101                    if (r != null && r.app != null && r.app.thread != null) {
2102                        try {
2103                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2104                        } catch (RemoteException e) {
2105                        }
2106                    }
2107                }
2108                break;
2109            }
2110            case FINISH_BOOTING_MSG: {
2111                if (msg.arg1 != 0) {
2112                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2113                    finishBooting();
2114                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2115                }
2116                if (msg.arg2 != 0) {
2117                    enableScreenAfterBoot();
2118                }
2119                break;
2120            }
2121            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2122                try {
2123                    Locale l = (Locale) msg.obj;
2124                    IBinder service = ServiceManager.getService("mount");
2125                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2126                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2127                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2128                } catch (RemoteException e) {
2129                    Log.e(TAG, "Error storing locale for decryption UI", e);
2130                }
2131                break;
2132            }
2133            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2134                final int uid = msg.arg1;
2135                final byte[] firstPacket = (byte[]) msg.obj;
2136
2137                synchronized (mPidsSelfLocked) {
2138                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2139                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2140                        if (p.uid == uid) {
2141                            try {
2142                                p.thread.notifyCleartextNetwork(firstPacket);
2143                            } catch (RemoteException ignored) {
2144                            }
2145                        }
2146                    }
2147                }
2148                break;
2149            }
2150            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2151                final String procName;
2152                final int uid;
2153                final long memLimit;
2154                final String reportPackage;
2155                synchronized (ActivityManagerService.this) {
2156                    procName = mMemWatchDumpProcName;
2157                    uid = mMemWatchDumpUid;
2158                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2159                    if (val == null) {
2160                        val = mMemWatchProcesses.get(procName, 0);
2161                    }
2162                    if (val != null) {
2163                        memLimit = val.first;
2164                        reportPackage = val.second;
2165                    } else {
2166                        memLimit = 0;
2167                        reportPackage = null;
2168                    }
2169                }
2170                if (procName == null) {
2171                    return;
2172                }
2173
2174                if (DEBUG_PSS) Slog.d(TAG_PSS,
2175                        "Showing dump heap notification from " + procName + "/" + uid);
2176
2177                INotificationManager inm = NotificationManager.getService();
2178                if (inm == null) {
2179                    return;
2180                }
2181
2182                String text = mContext.getString(R.string.dump_heap_notification, procName);
2183
2184
2185                Intent deleteIntent = new Intent();
2186                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2187                Intent intent = new Intent();
2188                intent.setClassName("android", DumpHeapActivity.class.getName());
2189                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2190                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2191                if (reportPackage != null) {
2192                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2193                }
2194                int userId = UserHandle.getUserId(uid);
2195                Notification notification = new Notification.Builder(mContext)
2196                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2197                        .setWhen(0)
2198                        .setOngoing(true)
2199                        .setAutoCancel(true)
2200                        .setTicker(text)
2201                        .setColor(mContext.getColor(
2202                                com.android.internal.R.color.system_notification_accent_color))
2203                        .setContentTitle(text)
2204                        .setContentText(
2205                                mContext.getText(R.string.dump_heap_notification_detail))
2206                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2207                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2208                                new UserHandle(userId)))
2209                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2210                                deleteIntent, 0, UserHandle.SYSTEM))
2211                        .build();
2212
2213                try {
2214                    int[] outId = new int[1];
2215                    inm.enqueueNotificationWithTag("android", "android", null,
2216                            R.string.dump_heap_notification,
2217                            notification, outId, userId);
2218                } catch (RuntimeException e) {
2219                    Slog.w(ActivityManagerService.TAG,
2220                            "Error showing notification for dump heap", e);
2221                } catch (RemoteException e) {
2222                }
2223            } break;
2224            case DELETE_DUMPHEAP_MSG: {
2225                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2226                        DumpHeapActivity.JAVA_URI,
2227                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2228                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2229                        UserHandle.myUserId());
2230                synchronized (ActivityManagerService.this) {
2231                    mMemWatchDumpFile = null;
2232                    mMemWatchDumpProcName = null;
2233                    mMemWatchDumpPid = -1;
2234                    mMemWatchDumpUid = -1;
2235                }
2236            } break;
2237            case FOREGROUND_PROFILE_CHANGED_MSG: {
2238                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2239            } break;
2240            case REPORT_TIME_TRACKER_MSG: {
2241                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2242                tracker.deliverResult(mContext);
2243            } break;
2244            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2245                mUserController.dispatchUserSwitchComplete(msg.arg1);
2246            } break;
2247            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2248                mUserController.dispatchLockedBootComplete(msg.arg1);
2249            } break;
2250            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2251                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2252                try {
2253                    connection.shutdown();
2254                } catch (RemoteException e) {
2255                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2256                }
2257                // Only a UiAutomation can set this flag and now that
2258                // it is finished we make sure it is reset to its default.
2259                mUserIsMonkey = false;
2260            } break;
2261            case IDLE_UIDS_MSG: {
2262                idleUids();
2263            } break;
2264            case VR_MODE_CHANGE_MSG: {
2265                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2266                if (vrService == null) {
2267                    break;
2268                }
2269                final ActivityRecord r = (ActivityRecord) msg.obj;
2270                boolean vrMode;
2271                ComponentName requestedPackage;
2272                ComponentName callingPackage;
2273                int userId;
2274                synchronized (ActivityManagerService.this) {
2275                    vrMode = r.requestedVrComponent != null;
2276                    requestedPackage = r.requestedVrComponent;
2277                    userId = r.userId;
2278                    callingPackage = r.info.getComponentName();
2279                    if (mInVrMode != vrMode) {
2280                        mInVrMode = vrMode;
2281                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2282                        if (r.app != null) {
2283                            ProcessRecord proc = r.app;
2284                            if (proc.vrThreadTid > 0) {
2285                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2286                                    try {
2287                                        if (mInVrMode == true) {
2288                                            Process.setThreadScheduler(proc.vrThreadTid,
2289                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2290                                        } else {
2291                                            Process.setThreadScheduler(proc.vrThreadTid,
2292                                                Process.SCHED_OTHER, 0);
2293                                        }
2294                                    } catch (IllegalArgumentException e) {
2295                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2296                                                + " not exist:\n" + e);
2297                                    }
2298                                }
2299                            }
2300                        }
2301                    }
2302                }
2303                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2304            } case NOTIFY_VR_SLEEPING_MSG: {
2305                notifyVrManagerOfSleepState(msg.arg1 != 0);
2306            } break;
2307            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2308                synchronized (ActivityManagerService.this) {
2309                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2310                        ProcessRecord r = mLruProcesses.get(i);
2311                        if (r.thread != null) {
2312                            try {
2313                                r.thread.handleTrustStorageUpdate();
2314                            } catch (RemoteException ex) {
2315                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2316                                        r.info.processName);
2317                            }
2318                        }
2319                    }
2320                }
2321            } break;
2322            }
2323        }
2324    };
2325
2326    static final int COLLECT_PSS_BG_MSG = 1;
2327
2328    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2329        @Override
2330        public void handleMessage(Message msg) {
2331            switch (msg.what) {
2332            case COLLECT_PSS_BG_MSG: {
2333                long start = SystemClock.uptimeMillis();
2334                MemInfoReader memInfo = null;
2335                synchronized (ActivityManagerService.this) {
2336                    if (mFullPssPending) {
2337                        mFullPssPending = false;
2338                        memInfo = new MemInfoReader();
2339                    }
2340                }
2341                if (memInfo != null) {
2342                    updateCpuStatsNow();
2343                    long nativeTotalPss = 0;
2344                    final List<ProcessCpuTracker.Stats> stats;
2345                    synchronized (mProcessCpuTracker) {
2346                        stats = mProcessCpuTracker.getStats( (st)-> {
2347                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2348                        });
2349                    }
2350                    final int N = stats.size();
2351                    for (int j = 0; j < N; j++) {
2352                        synchronized (mPidsSelfLocked) {
2353                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2354                                // This is one of our own processes; skip it.
2355                                continue;
2356                            }
2357                        }
2358                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2359                    }
2360                    memInfo.readMemInfo();
2361                    synchronized (ActivityManagerService.this) {
2362                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2363                                + (SystemClock.uptimeMillis()-start) + "ms");
2364                        final long cachedKb = memInfo.getCachedSizeKb();
2365                        final long freeKb = memInfo.getFreeSizeKb();
2366                        final long zramKb = memInfo.getZramTotalSizeKb();
2367                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2368                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2369                                kernelKb*1024, nativeTotalPss*1024);
2370                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2371                                nativeTotalPss);
2372                    }
2373                }
2374
2375                int num = 0;
2376                long[] tmp = new long[2];
2377                do {
2378                    ProcessRecord proc;
2379                    int procState;
2380                    int pid;
2381                    long lastPssTime;
2382                    synchronized (ActivityManagerService.this) {
2383                        if (mPendingPssProcesses.size() <= 0) {
2384                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2385                                    "Collected PSS of " + num + " processes in "
2386                                    + (SystemClock.uptimeMillis() - start) + "ms");
2387                            mPendingPssProcesses.clear();
2388                            return;
2389                        }
2390                        proc = mPendingPssProcesses.remove(0);
2391                        procState = proc.pssProcState;
2392                        lastPssTime = proc.lastPssTime;
2393                        if (proc.thread != null && procState == proc.setProcState
2394                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2395                                        < SystemClock.uptimeMillis()) {
2396                            pid = proc.pid;
2397                        } else {
2398                            proc = null;
2399                            pid = 0;
2400                        }
2401                    }
2402                    if (proc != null) {
2403                        long pss = Debug.getPss(pid, tmp, null);
2404                        synchronized (ActivityManagerService.this) {
2405                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2406                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2407                                num++;
2408                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2409                                        SystemClock.uptimeMillis());
2410                            }
2411                        }
2412                    }
2413                } while (true);
2414            }
2415            }
2416        }
2417    };
2418
2419    public void setSystemProcess() {
2420        try {
2421            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2422            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2423            ServiceManager.addService("meminfo", new MemBinder(this));
2424            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2425            ServiceManager.addService("dbinfo", new DbBinder(this));
2426            if (MONITOR_CPU_USAGE) {
2427                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2428            }
2429            ServiceManager.addService("permission", new PermissionController(this));
2430            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2431
2432            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2433                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2434            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2435
2436            synchronized (this) {
2437                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2438                app.persistent = true;
2439                app.pid = MY_PID;
2440                app.maxAdj = ProcessList.SYSTEM_ADJ;
2441                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2442                synchronized (mPidsSelfLocked) {
2443                    mPidsSelfLocked.put(app.pid, app);
2444                }
2445                updateLruProcessLocked(app, false, null);
2446                updateOomAdjLocked();
2447            }
2448        } catch (PackageManager.NameNotFoundException e) {
2449            throw new RuntimeException(
2450                    "Unable to find android system package", e);
2451        }
2452    }
2453
2454    public void setWindowManager(WindowManagerService wm) {
2455        mWindowManager = wm;
2456        mStackSupervisor.setWindowManager(wm);
2457        mActivityStarter.setWindowManager(wm);
2458    }
2459
2460    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2461        mUsageStatsService = usageStatsManager;
2462    }
2463
2464    public void startObservingNativeCrashes() {
2465        final NativeCrashListener ncl = new NativeCrashListener(this);
2466        ncl.start();
2467    }
2468
2469    public IAppOpsService getAppOpsService() {
2470        return mAppOpsService;
2471    }
2472
2473    static class MemBinder extends Binder {
2474        ActivityManagerService mActivityManagerService;
2475        MemBinder(ActivityManagerService activityManagerService) {
2476            mActivityManagerService = activityManagerService;
2477        }
2478
2479        @Override
2480        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2481            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2482                    != PackageManager.PERMISSION_GRANTED) {
2483                pw.println("Permission Denial: can't dump meminfo from from pid="
2484                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2485                        + " without permission " + android.Manifest.permission.DUMP);
2486                return;
2487            }
2488
2489            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2490        }
2491    }
2492
2493    static class GraphicsBinder extends Binder {
2494        ActivityManagerService mActivityManagerService;
2495        GraphicsBinder(ActivityManagerService activityManagerService) {
2496            mActivityManagerService = activityManagerService;
2497        }
2498
2499        @Override
2500        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2501            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2502                    != PackageManager.PERMISSION_GRANTED) {
2503                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2504                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2505                        + " without permission " + android.Manifest.permission.DUMP);
2506                return;
2507            }
2508
2509            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2510        }
2511    }
2512
2513    static class DbBinder extends Binder {
2514        ActivityManagerService mActivityManagerService;
2515        DbBinder(ActivityManagerService activityManagerService) {
2516            mActivityManagerService = activityManagerService;
2517        }
2518
2519        @Override
2520        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2521            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2522                    != PackageManager.PERMISSION_GRANTED) {
2523                pw.println("Permission Denial: can't dump dbinfo from from pid="
2524                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2525                        + " without permission " + android.Manifest.permission.DUMP);
2526                return;
2527            }
2528
2529            mActivityManagerService.dumpDbInfo(fd, pw, args);
2530        }
2531    }
2532
2533    static class CpuBinder extends Binder {
2534        ActivityManagerService mActivityManagerService;
2535        CpuBinder(ActivityManagerService activityManagerService) {
2536            mActivityManagerService = activityManagerService;
2537        }
2538
2539        @Override
2540        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2541            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2542                    != PackageManager.PERMISSION_GRANTED) {
2543                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2544                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2545                        + " without permission " + android.Manifest.permission.DUMP);
2546                return;
2547            }
2548
2549            synchronized (mActivityManagerService.mProcessCpuTracker) {
2550                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2551                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2552                        SystemClock.uptimeMillis()));
2553            }
2554        }
2555    }
2556
2557    public static final class Lifecycle extends SystemService {
2558        private final ActivityManagerService mService;
2559
2560        public Lifecycle(Context context) {
2561            super(context);
2562            mService = new ActivityManagerService(context);
2563        }
2564
2565        @Override
2566        public void onStart() {
2567            mService.start();
2568        }
2569
2570        public ActivityManagerService getService() {
2571            return mService;
2572        }
2573    }
2574
2575    // Note: This method is invoked on the main thread but may need to attach various
2576    // handlers to other threads.  So take care to be explicit about the looper.
2577    public ActivityManagerService(Context systemContext) {
2578        mContext = systemContext;
2579        mFactoryTest = FactoryTest.getMode();
2580        mSystemThread = ActivityThread.currentActivityThread();
2581
2582        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2583
2584        mPermissionReviewRequired = mContext.getResources().getBoolean(
2585                com.android.internal.R.bool.config_permissionReviewRequired);
2586
2587        mHandlerThread = new ServiceThread(TAG,
2588                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2589        mHandlerThread.start();
2590        mHandler = new MainHandler(mHandlerThread.getLooper());
2591        mUiHandler = new UiHandler();
2592
2593        /* static; one-time init here */
2594        if (sKillHandler == null) {
2595            sKillThread = new ServiceThread(TAG + ":kill",
2596                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2597            sKillThread.start();
2598            sKillHandler = new KillHandler(sKillThread.getLooper());
2599        }
2600
2601        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2602                "foreground", BROADCAST_FG_TIMEOUT, false);
2603        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2604                "background", BROADCAST_BG_TIMEOUT, true);
2605        mBroadcastQueues[0] = mFgBroadcastQueue;
2606        mBroadcastQueues[1] = mBgBroadcastQueue;
2607
2608        mServices = new ActiveServices(this);
2609        mProviderMap = new ProviderMap(this);
2610        mAppErrors = new AppErrors(mContext, this);
2611
2612        // TODO: Move creation of battery stats service outside of activity manager service.
2613        File dataDir = Environment.getDataDirectory();
2614        File systemDir = new File(dataDir, "system");
2615        systemDir.mkdirs();
2616        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2617        mBatteryStatsService.getActiveStatistics().readLocked();
2618        mBatteryStatsService.scheduleWriteToDisk();
2619        mOnBattery = DEBUG_POWER ? true
2620                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2621        mBatteryStatsService.getActiveStatistics().setCallback(this);
2622
2623        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2624
2625        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2626        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2627                new IAppOpsCallback.Stub() {
2628                    @Override public void opChanged(int op, int uid, String packageName) {
2629                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2630                            if (mAppOpsService.checkOperation(op, uid, packageName)
2631                                    != AppOpsManager.MODE_ALLOWED) {
2632                                runInBackgroundDisabled(uid);
2633                            }
2634                        }
2635                    }
2636                });
2637
2638        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2639
2640        mUserController = new UserController(this);
2641
2642        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2643            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2644
2645        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2646            mUseFifoUiScheduling = true;
2647        }
2648
2649        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2650
2651        mTempConfig.setToDefaults();
2652        mTempConfig.setLocales(LocaleList.getDefault());
2653        mConfigurationSeq = mTempConfig.seq = 1;
2654
2655        mProcessCpuTracker.init();
2656
2657        mStackSupervisor = new ActivityStackSupervisor(this);
2658        mStackSupervisor.onConfigurationChanged(mTempConfig);
2659        mKeyguardController = mStackSupervisor.mKeyguardController;
2660        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2661        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2662        mTaskChangeNotificationController =
2663                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2664        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2665        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2666
2667        mProcessCpuThread = new Thread("CpuTracker") {
2668            @Override
2669            public void run() {
2670                while (true) {
2671                    try {
2672                        try {
2673                            synchronized(this) {
2674                                final long now = SystemClock.uptimeMillis();
2675                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2676                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2677                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2678                                //        + ", write delay=" + nextWriteDelay);
2679                                if (nextWriteDelay < nextCpuDelay) {
2680                                    nextCpuDelay = nextWriteDelay;
2681                                }
2682                                if (nextCpuDelay > 0) {
2683                                    mProcessCpuMutexFree.set(true);
2684                                    this.wait(nextCpuDelay);
2685                                }
2686                            }
2687                        } catch (InterruptedException e) {
2688                        }
2689                        updateCpuStatsNow();
2690                    } catch (Exception e) {
2691                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2692                    }
2693                }
2694            }
2695        };
2696
2697        Watchdog.getInstance().addMonitor(this);
2698        Watchdog.getInstance().addThread(mHandler);
2699    }
2700
2701    public void setSystemServiceManager(SystemServiceManager mgr) {
2702        mSystemServiceManager = mgr;
2703    }
2704
2705    public void setInstaller(Installer installer) {
2706        mInstaller = installer;
2707    }
2708
2709    private void start() {
2710        Process.removeAllProcessGroups();
2711        mProcessCpuThread.start();
2712
2713        mBatteryStatsService.publish(mContext);
2714        mAppOpsService.publish(mContext);
2715        Slog.d("AppOps", "AppOpsService published");
2716        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2717    }
2718
2719    void onUserStoppedLocked(int userId) {
2720        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2721    }
2722
2723    public void initPowerManagement() {
2724        mStackSupervisor.initPowerManagement();
2725        mBatteryStatsService.initPowerManagement();
2726        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2727        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2728        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2729        mVoiceWakeLock.setReferenceCounted(false);
2730    }
2731
2732    @Override
2733    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2734            throws RemoteException {
2735        if (code == SYSPROPS_TRANSACTION) {
2736            // We need to tell all apps about the system property change.
2737            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2738            synchronized(this) {
2739                final int NP = mProcessNames.getMap().size();
2740                for (int ip=0; ip<NP; ip++) {
2741                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2742                    final int NA = apps.size();
2743                    for (int ia=0; ia<NA; ia++) {
2744                        ProcessRecord app = apps.valueAt(ia);
2745                        if (app.thread != null) {
2746                            procs.add(app.thread.asBinder());
2747                        }
2748                    }
2749                }
2750            }
2751
2752            int N = procs.size();
2753            for (int i=0; i<N; i++) {
2754                Parcel data2 = Parcel.obtain();
2755                try {
2756                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2757                            Binder.FLAG_ONEWAY);
2758                } catch (RemoteException e) {
2759                }
2760                data2.recycle();
2761            }
2762        }
2763        try {
2764            return super.onTransact(code, data, reply, flags);
2765        } catch (RuntimeException e) {
2766            // The activity manager only throws security exceptions, so let's
2767            // log all others.
2768            if (!(e instanceof SecurityException)) {
2769                Slog.wtf(TAG, "Activity Manager Crash", e);
2770            }
2771            throw e;
2772        }
2773    }
2774
2775    void updateCpuStats() {
2776        final long now = SystemClock.uptimeMillis();
2777        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2778            return;
2779        }
2780        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2781            synchronized (mProcessCpuThread) {
2782                mProcessCpuThread.notify();
2783            }
2784        }
2785    }
2786
2787    void updateCpuStatsNow() {
2788        synchronized (mProcessCpuTracker) {
2789            mProcessCpuMutexFree.set(false);
2790            final long now = SystemClock.uptimeMillis();
2791            boolean haveNewCpuStats = false;
2792
2793            if (MONITOR_CPU_USAGE &&
2794                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2795                mLastCpuTime.set(now);
2796                mProcessCpuTracker.update();
2797                if (mProcessCpuTracker.hasGoodLastStats()) {
2798                    haveNewCpuStats = true;
2799                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2800                    //Slog.i(TAG, "Total CPU usage: "
2801                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2802
2803                    // Slog the cpu usage if the property is set.
2804                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2805                        int user = mProcessCpuTracker.getLastUserTime();
2806                        int system = mProcessCpuTracker.getLastSystemTime();
2807                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2808                        int irq = mProcessCpuTracker.getLastIrqTime();
2809                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2810                        int idle = mProcessCpuTracker.getLastIdleTime();
2811
2812                        int total = user + system + iowait + irq + softIrq + idle;
2813                        if (total == 0) total = 1;
2814
2815                        EventLog.writeEvent(EventLogTags.CPU,
2816                                ((user+system+iowait+irq+softIrq) * 100) / total,
2817                                (user * 100) / total,
2818                                (system * 100) / total,
2819                                (iowait * 100) / total,
2820                                (irq * 100) / total,
2821                                (softIrq * 100) / total);
2822                    }
2823                }
2824            }
2825
2826            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2827            synchronized(bstats) {
2828                synchronized(mPidsSelfLocked) {
2829                    if (haveNewCpuStats) {
2830                        if (bstats.startAddingCpuLocked()) {
2831                            int totalUTime = 0;
2832                            int totalSTime = 0;
2833                            final int N = mProcessCpuTracker.countStats();
2834                            for (int i=0; i<N; i++) {
2835                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2836                                if (!st.working) {
2837                                    continue;
2838                                }
2839                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2840                                totalUTime += st.rel_utime;
2841                                totalSTime += st.rel_stime;
2842                                if (pr != null) {
2843                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2844                                    if (ps == null || !ps.isActive()) {
2845                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2846                                                pr.info.uid, pr.processName);
2847                                    }
2848                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2849                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2850                                } else {
2851                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2852                                    if (ps == null || !ps.isActive()) {
2853                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2854                                                bstats.mapUid(st.uid), st.name);
2855                                    }
2856                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2857                                }
2858                            }
2859                            final int userTime = mProcessCpuTracker.getLastUserTime();
2860                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2861                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2862                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2863                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2864                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2865                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2866                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2867                        }
2868                    }
2869                }
2870
2871                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2872                    mLastWriteTime = now;
2873                    mBatteryStatsService.scheduleWriteToDisk();
2874                }
2875            }
2876        }
2877    }
2878
2879    @Override
2880    public void batteryNeedsCpuUpdate() {
2881        updateCpuStatsNow();
2882    }
2883
2884    @Override
2885    public void batteryPowerChanged(boolean onBattery) {
2886        // When plugging in, update the CPU stats first before changing
2887        // the plug state.
2888        updateCpuStatsNow();
2889        synchronized (this) {
2890            synchronized(mPidsSelfLocked) {
2891                mOnBattery = DEBUG_POWER ? true : onBattery;
2892            }
2893        }
2894    }
2895
2896    @Override
2897    public void batterySendBroadcast(Intent intent) {
2898        synchronized (this) {
2899            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2900                    AppOpsManager.OP_NONE, null, false, false,
2901                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2902        }
2903    }
2904
2905    /**
2906     * Initialize the application bind args. These are passed to each
2907     * process when the bindApplication() IPC is sent to the process. They're
2908     * lazily setup to make sure the services are running when they're asked for.
2909     */
2910    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2911        // Isolated processes won't get this optimization, so that we don't
2912        // violate the rules about which services they have access to.
2913        if (isolated) {
2914            if (mIsolatedAppBindArgs == null) {
2915                mIsolatedAppBindArgs = new HashMap<>();
2916                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2917            }
2918            return mIsolatedAppBindArgs;
2919        }
2920
2921        if (mAppBindArgs == null) {
2922            mAppBindArgs = new HashMap<>();
2923
2924            // Setup the application init args
2925            mAppBindArgs.put("package", ServiceManager.getService("package"));
2926            mAppBindArgs.put("window", ServiceManager.getService("window"));
2927            mAppBindArgs.put(Context.ALARM_SERVICE,
2928                    ServiceManager.getService(Context.ALARM_SERVICE));
2929        }
2930        return mAppBindArgs;
2931    }
2932
2933    /**
2934     * Update AMS states when an activity is resumed. This should only be called by
2935     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2936     */
2937    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2938        if (r.task.isApplicationTask()) {
2939            if (mCurAppTimeTracker != r.appTimeTracker) {
2940                // We are switching app tracking.  Complete the current one.
2941                if (mCurAppTimeTracker != null) {
2942                    mCurAppTimeTracker.stop();
2943                    mHandler.obtainMessage(
2944                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2945                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2946                    mCurAppTimeTracker = null;
2947                }
2948                if (r.appTimeTracker != null) {
2949                    mCurAppTimeTracker = r.appTimeTracker;
2950                    startTimeTrackingFocusedActivityLocked();
2951                }
2952            } else {
2953                startTimeTrackingFocusedActivityLocked();
2954            }
2955        } else {
2956            r.appTimeTracker = null;
2957        }
2958        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2959        // TODO: Probably not, because we don't want to resume voice on switching
2960        // back to this activity
2961        if (r.task.voiceInteractor != null) {
2962            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2963        } else {
2964            finishRunningVoiceLocked();
2965            IVoiceInteractionSession session;
2966            if (mLastResumedActivity != null
2967                    && ((session = mLastResumedActivity.task.voiceSession) != null
2968                    || (session = mLastResumedActivity.voiceSession) != null)) {
2969                // We had been in a voice interaction session, but now focused has
2970                // move to something different.  Just finish the session, we can't
2971                // return to it and retain the proper state and synchronization with
2972                // the voice interaction service.
2973                finishVoiceTask(session);
2974            }
2975        }
2976
2977        mWindowManager.setFocusedApp(r.appToken, true);
2978
2979        applyUpdateLockStateLocked(r);
2980        applyUpdateVrModeLocked(r);
2981        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2982            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2983            mHandler.obtainMessage(
2984                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
2985        }
2986
2987        mLastResumedActivity = r;
2988
2989        EventLogTags.writeAmSetResumedActivity(
2990                r == null ? -1 : r.userId,
2991                r == null ? "NULL" : r.shortComponentName,
2992                reason);
2993    }
2994
2995    @Override
2996    public void setFocusedStack(int stackId) {
2997        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2998        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2999        final long callingId = Binder.clearCallingIdentity();
3000        try {
3001            synchronized (this) {
3002                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3003                if (stack == null) {
3004                    return;
3005                }
3006                final ActivityRecord r = stack.topRunningActivityLocked();
3007                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3008                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3009                }
3010            }
3011        } finally {
3012            Binder.restoreCallingIdentity(callingId);
3013        }
3014    }
3015
3016    @Override
3017    public void setFocusedTask(int taskId) {
3018        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3019        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3020        final long callingId = Binder.clearCallingIdentity();
3021        try {
3022            synchronized (this) {
3023                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3024                if (task == null) {
3025                    return;
3026                }
3027                final ActivityRecord r = task.topRunningActivityLocked();
3028                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3029                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3030                }
3031            }
3032        } finally {
3033            Binder.restoreCallingIdentity(callingId);
3034        }
3035    }
3036
3037    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3038    @Override
3039    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3040        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3041        mTaskChangeNotificationController.registerTaskStackListener(listener);
3042    }
3043
3044    /**
3045     * Unregister a task stack listener so that it stops receiving callbacks.
3046     */
3047    @Override
3048    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3049         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3050         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3051     }
3052
3053    @Override
3054    public void notifyActivityDrawn(IBinder token) {
3055        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056        synchronized (this) {
3057            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3058            if (r != null) {
3059                r.getStack().notifyActivityDrawnLocked(r);
3060            }
3061        }
3062    }
3063
3064    final void applyUpdateLockStateLocked(ActivityRecord r) {
3065        // Modifications to the UpdateLock state are done on our handler, outside
3066        // the activity manager's locks.  The new state is determined based on the
3067        // state *now* of the relevant activity record.  The object is passed to
3068        // the handler solely for logging detail, not to be consulted/modified.
3069        final boolean nextState = r != null && r.immersive;
3070        mHandler.sendMessage(
3071                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3072    }
3073
3074    final void applyUpdateVrModeLocked(ActivityRecord r) {
3075        mHandler.sendMessage(
3076                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3077    }
3078
3079    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3080        mHandler.sendMessage(
3081                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3082    }
3083
3084    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3085        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3086        if (vrService == null) {
3087            return;
3088        }
3089        vrService.onSleepStateChanged(isSleeping);
3090    }
3091
3092    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3093        Message msg = Message.obtain();
3094        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3095        msg.obj = r.task.askedCompatMode ? null : r;
3096        mUiHandler.sendMessage(msg);
3097    }
3098
3099    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3100        final Configuration globalConfig = getGlobalConfiguration();
3101        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3102                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3103            final Message msg = Message.obtain();
3104            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3105            msg.obj = r;
3106            mUiHandler.sendMessage(msg);
3107        }
3108    }
3109
3110    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3111            String what, Object obj, ProcessRecord srcApp) {
3112        app.lastActivityTime = now;
3113
3114        if (app.activities.size() > 0) {
3115            // Don't want to touch dependent processes that are hosting activities.
3116            return index;
3117        }
3118
3119        int lrui = mLruProcesses.lastIndexOf(app);
3120        if (lrui < 0) {
3121            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3122                    + what + " " + obj + " from " + srcApp);
3123            return index;
3124        }
3125
3126        if (lrui >= index) {
3127            // Don't want to cause this to move dependent processes *back* in the
3128            // list as if they were less frequently used.
3129            return index;
3130        }
3131
3132        if (lrui >= mLruProcessActivityStart) {
3133            // Don't want to touch dependent processes that are hosting activities.
3134            return index;
3135        }
3136
3137        mLruProcesses.remove(lrui);
3138        if (index > 0) {
3139            index--;
3140        }
3141        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3142                + " in LRU list: " + app);
3143        mLruProcesses.add(index, app);
3144        return index;
3145    }
3146
3147    static void killProcessGroup(int uid, int pid) {
3148        if (sKillHandler != null) {
3149            sKillHandler.sendMessage(
3150                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3151        } else {
3152            Slog.w(TAG, "Asked to kill process group before system bringup!");
3153            Process.killProcessGroup(uid, pid);
3154        }
3155    }
3156
3157    final void removeLruProcessLocked(ProcessRecord app) {
3158        int lrui = mLruProcesses.lastIndexOf(app);
3159        if (lrui >= 0) {
3160            if (!app.killed) {
3161                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3162                Process.killProcessQuiet(app.pid);
3163                killProcessGroup(app.uid, app.pid);
3164            }
3165            if (lrui <= mLruProcessActivityStart) {
3166                mLruProcessActivityStart--;
3167            }
3168            if (lrui <= mLruProcessServiceStart) {
3169                mLruProcessServiceStart--;
3170            }
3171            mLruProcesses.remove(lrui);
3172        }
3173    }
3174
3175    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3176            ProcessRecord client) {
3177        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3178                || app.treatLikeActivity;
3179        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3180        if (!activityChange && hasActivity) {
3181            // The process has activities, so we are only allowing activity-based adjustments
3182            // to move it.  It should be kept in the front of the list with other
3183            // processes that have activities, and we don't want those to change their
3184            // order except due to activity operations.
3185            return;
3186        }
3187
3188        mLruSeq++;
3189        final long now = SystemClock.uptimeMillis();
3190        app.lastActivityTime = now;
3191
3192        // First a quick reject: if the app is already at the position we will
3193        // put it, then there is nothing to do.
3194        if (hasActivity) {
3195            final int N = mLruProcesses.size();
3196            if (N > 0 && mLruProcesses.get(N-1) == app) {
3197                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3198                return;
3199            }
3200        } else {
3201            if (mLruProcessServiceStart > 0
3202                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3203                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3204                return;
3205            }
3206        }
3207
3208        int lrui = mLruProcesses.lastIndexOf(app);
3209
3210        if (app.persistent && lrui >= 0) {
3211            // We don't care about the position of persistent processes, as long as
3212            // they are in the list.
3213            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3214            return;
3215        }
3216
3217        /* In progress: compute new position first, so we can avoid doing work
3218           if the process is not actually going to move.  Not yet working.
3219        int addIndex;
3220        int nextIndex;
3221        boolean inActivity = false, inService = false;
3222        if (hasActivity) {
3223            // Process has activities, put it at the very tipsy-top.
3224            addIndex = mLruProcesses.size();
3225            nextIndex = mLruProcessServiceStart;
3226            inActivity = true;
3227        } else if (hasService) {
3228            // Process has services, put it at the top of the service list.
3229            addIndex = mLruProcessActivityStart;
3230            nextIndex = mLruProcessServiceStart;
3231            inActivity = true;
3232            inService = true;
3233        } else  {
3234            // Process not otherwise of interest, it goes to the top of the non-service area.
3235            addIndex = mLruProcessServiceStart;
3236            if (client != null) {
3237                int clientIndex = mLruProcesses.lastIndexOf(client);
3238                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3239                        + app);
3240                if (clientIndex >= 0 && addIndex > clientIndex) {
3241                    addIndex = clientIndex;
3242                }
3243            }
3244            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3245        }
3246
3247        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3248                + mLruProcessActivityStart + "): " + app);
3249        */
3250
3251        if (lrui >= 0) {
3252            if (lrui < mLruProcessActivityStart) {
3253                mLruProcessActivityStart--;
3254            }
3255            if (lrui < mLruProcessServiceStart) {
3256                mLruProcessServiceStart--;
3257            }
3258            /*
3259            if (addIndex > lrui) {
3260                addIndex--;
3261            }
3262            if (nextIndex > lrui) {
3263                nextIndex--;
3264            }
3265            */
3266            mLruProcesses.remove(lrui);
3267        }
3268
3269        /*
3270        mLruProcesses.add(addIndex, app);
3271        if (inActivity) {
3272            mLruProcessActivityStart++;
3273        }
3274        if (inService) {
3275            mLruProcessActivityStart++;
3276        }
3277        */
3278
3279        int nextIndex;
3280        if (hasActivity) {
3281            final int N = mLruProcesses.size();
3282            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3283                // Process doesn't have activities, but has clients with
3284                // activities...  move it up, but one below the top (the top
3285                // should always have a real activity).
3286                if (DEBUG_LRU) Slog.d(TAG_LRU,
3287                        "Adding to second-top of LRU activity list: " + app);
3288                mLruProcesses.add(N - 1, app);
3289                // To keep it from spamming the LRU list (by making a bunch of clients),
3290                // we will push down any other entries owned by the app.
3291                final int uid = app.info.uid;
3292                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3293                    ProcessRecord subProc = mLruProcesses.get(i);
3294                    if (subProc.info.uid == uid) {
3295                        // We want to push this one down the list.  If the process after
3296                        // it is for the same uid, however, don't do so, because we don't
3297                        // want them internally to be re-ordered.
3298                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3299                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3300                                    "Pushing uid " + uid + " swapping at " + i + ": "
3301                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3302                            ProcessRecord tmp = mLruProcesses.get(i);
3303                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3304                            mLruProcesses.set(i - 1, tmp);
3305                            i--;
3306                        }
3307                    } else {
3308                        // A gap, we can stop here.
3309                        break;
3310                    }
3311                }
3312            } else {
3313                // Process has activities, put it at the very tipsy-top.
3314                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3315                mLruProcesses.add(app);
3316            }
3317            nextIndex = mLruProcessServiceStart;
3318        } else if (hasService) {
3319            // Process has services, put it at the top of the service list.
3320            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3321            mLruProcesses.add(mLruProcessActivityStart, app);
3322            nextIndex = mLruProcessServiceStart;
3323            mLruProcessActivityStart++;
3324        } else  {
3325            // Process not otherwise of interest, it goes to the top of the non-service area.
3326            int index = mLruProcessServiceStart;
3327            if (client != null) {
3328                // If there is a client, don't allow the process to be moved up higher
3329                // in the list than that client.
3330                int clientIndex = mLruProcesses.lastIndexOf(client);
3331                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3332                        + " when updating " + app);
3333                if (clientIndex <= lrui) {
3334                    // Don't allow the client index restriction to push it down farther in the
3335                    // list than it already is.
3336                    clientIndex = lrui;
3337                }
3338                if (clientIndex >= 0 && index > clientIndex) {
3339                    index = clientIndex;
3340                }
3341            }
3342            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3343            mLruProcesses.add(index, app);
3344            nextIndex = index-1;
3345            mLruProcessActivityStart++;
3346            mLruProcessServiceStart++;
3347        }
3348
3349        // If the app is currently using a content provider or service,
3350        // bump those processes as well.
3351        for (int j=app.connections.size()-1; j>=0; j--) {
3352            ConnectionRecord cr = app.connections.valueAt(j);
3353            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3354                    && cr.binding.service.app != null
3355                    && cr.binding.service.app.lruSeq != mLruSeq
3356                    && !cr.binding.service.app.persistent) {
3357                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3358                        "service connection", cr, app);
3359            }
3360        }
3361        for (int j=app.conProviders.size()-1; j>=0; j--) {
3362            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3363            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3364                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3365                        "provider reference", cpr, app);
3366            }
3367        }
3368    }
3369
3370    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3371        if (uid == Process.SYSTEM_UID) {
3372            // The system gets to run in any process.  If there are multiple
3373            // processes with the same uid, just pick the first (this
3374            // should never happen).
3375            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3376            if (procs == null) return null;
3377            final int procCount = procs.size();
3378            for (int i = 0; i < procCount; i++) {
3379                final int procUid = procs.keyAt(i);
3380                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3381                    // Don't use an app process or different user process for system component.
3382                    continue;
3383                }
3384                return procs.valueAt(i);
3385            }
3386        }
3387        ProcessRecord proc = mProcessNames.get(processName, uid);
3388        if (false && proc != null && !keepIfLarge
3389                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3390                && proc.lastCachedPss >= 4000) {
3391            // Turn this condition on to cause killing to happen regularly, for testing.
3392            if (proc.baseProcessTracker != null) {
3393                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3394            }
3395            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3396        } else if (proc != null && !keepIfLarge
3397                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3398                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3399            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3400            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3401                if (proc.baseProcessTracker != null) {
3402                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3403                }
3404                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3405            }
3406        }
3407        return proc;
3408    }
3409
3410    void notifyPackageUse(String packageName, int reason) {
3411        IPackageManager pm = AppGlobals.getPackageManager();
3412        try {
3413            pm.notifyPackageUse(packageName, reason);
3414        } catch (RemoteException e) {
3415        }
3416    }
3417
3418    boolean isNextTransitionForward() {
3419        int transit = mWindowManager.getPendingAppTransition();
3420        return transit == TRANSIT_ACTIVITY_OPEN
3421                || transit == TRANSIT_TASK_OPEN
3422                || transit == TRANSIT_TASK_TO_FRONT;
3423    }
3424
3425    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3426            String processName, String abiOverride, int uid, Runnable crashHandler) {
3427        synchronized(this) {
3428            ApplicationInfo info = new ApplicationInfo();
3429            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3430            // For isolated processes, the former contains the parent's uid and the latter the
3431            // actual uid of the isolated process.
3432            // In the special case introduced by this method (which is, starting an isolated
3433            // process directly from the SystemServer without an actual parent app process) the
3434            // closest thing to a parent's uid is SYSTEM_UID.
3435            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3436            // the |isolated| logic in the ProcessRecord constructor.
3437            info.uid = Process.SYSTEM_UID;
3438            info.processName = processName;
3439            info.className = entryPoint;
3440            info.packageName = "android";
3441            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3442                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3443                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3444                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3445                    crashHandler);
3446            return proc != null ? proc.pid : 0;
3447        }
3448    }
3449
3450    final ProcessRecord startProcessLocked(String processName,
3451            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3452            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3453            boolean isolated, boolean keepIfLarge) {
3454        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3455                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3456                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3457                null /* crashHandler */);
3458    }
3459
3460    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3461            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3462            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3463            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3464        long startTime = SystemClock.elapsedRealtime();
3465        ProcessRecord app;
3466        if (!isolated) {
3467            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3468            checkTime(startTime, "startProcess: after getProcessRecord");
3469
3470            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3471                // If we are in the background, then check to see if this process
3472                // is bad.  If so, we will just silently fail.
3473                if (mAppErrors.isBadProcessLocked(info)) {
3474                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3475                            + "/" + info.processName);
3476                    return null;
3477                }
3478            } else {
3479                // When the user is explicitly starting a process, then clear its
3480                // crash count so that we won't make it bad until they see at
3481                // least one crash dialog again, and make the process good again
3482                // if it had been bad.
3483                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3484                        + "/" + info.processName);
3485                mAppErrors.resetProcessCrashTimeLocked(info);
3486                if (mAppErrors.isBadProcessLocked(info)) {
3487                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3488                            UserHandle.getUserId(info.uid), info.uid,
3489                            info.processName);
3490                    mAppErrors.clearBadProcessLocked(info);
3491                    if (app != null) {
3492                        app.bad = false;
3493                    }
3494                }
3495            }
3496        } else {
3497            // If this is an isolated process, it can't re-use an existing process.
3498            app = null;
3499        }
3500
3501        // We don't have to do anything more if:
3502        // (1) There is an existing application record; and
3503        // (2) The caller doesn't think it is dead, OR there is no thread
3504        //     object attached to it so we know it couldn't have crashed; and
3505        // (3) There is a pid assigned to it, so it is either starting or
3506        //     already running.
3507        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3508                + " app=" + app + " knownToBeDead=" + knownToBeDead
3509                + " thread=" + (app != null ? app.thread : null)
3510                + " pid=" + (app != null ? app.pid : -1));
3511        if (app != null && app.pid > 0) {
3512            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3513                // We already have the app running, or are waiting for it to
3514                // come up (we have a pid but not yet its thread), so keep it.
3515                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3516                // If this is a new package in the process, add the package to the list
3517                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3518                checkTime(startTime, "startProcess: done, added package to proc");
3519                return app;
3520            }
3521
3522            // An application record is attached to a previous process,
3523            // clean it up now.
3524            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3525            checkTime(startTime, "startProcess: bad proc running, killing");
3526            killProcessGroup(app.uid, app.pid);
3527            handleAppDiedLocked(app, true, true);
3528            checkTime(startTime, "startProcess: done killing old proc");
3529        }
3530
3531        String hostingNameStr = hostingName != null
3532                ? hostingName.flattenToShortString() : null;
3533
3534        if (app == null) {
3535            checkTime(startTime, "startProcess: creating new process record");
3536            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3537            if (app == null) {
3538                Slog.w(TAG, "Failed making new process record for "
3539                        + processName + "/" + info.uid + " isolated=" + isolated);
3540                return null;
3541            }
3542            app.crashHandler = crashHandler;
3543            checkTime(startTime, "startProcess: done creating new process record");
3544        } else {
3545            // If this is a new package in the process, add the package to the list
3546            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3547            checkTime(startTime, "startProcess: added package to existing proc");
3548        }
3549
3550        // If the system is not ready yet, then hold off on starting this
3551        // process until it is.
3552        if (!mProcessesReady
3553                && !isAllowedWhileBooting(info)
3554                && !allowWhileBooting) {
3555            if (!mProcessesOnHold.contains(app)) {
3556                mProcessesOnHold.add(app);
3557            }
3558            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3559                    "System not ready, putting on hold: " + app);
3560            checkTime(startTime, "startProcess: returning with proc on hold");
3561            return app;
3562        }
3563
3564        checkTime(startTime, "startProcess: stepping in to startProcess");
3565        startProcessLocked(
3566                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3567        checkTime(startTime, "startProcess: done starting proc!");
3568        return (app.pid != 0) ? app : null;
3569    }
3570
3571    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3572        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3573    }
3574
3575    private final void startProcessLocked(ProcessRecord app,
3576            String hostingType, String hostingNameStr) {
3577        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3578                null /* entryPoint */, null /* entryPointArgs */);
3579    }
3580
3581    private final void startProcessLocked(ProcessRecord app, String hostingType,
3582            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3583        long startTime = SystemClock.elapsedRealtime();
3584        if (app.pid > 0 && app.pid != MY_PID) {
3585            checkTime(startTime, "startProcess: removing from pids map");
3586            synchronized (mPidsSelfLocked) {
3587                mPidsSelfLocked.remove(app.pid);
3588                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3589            }
3590            checkTime(startTime, "startProcess: done removing from pids map");
3591            app.setPid(0);
3592        }
3593
3594        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3595                "startProcessLocked removing on hold: " + app);
3596        mProcessesOnHold.remove(app);
3597
3598        checkTime(startTime, "startProcess: starting to update cpu stats");
3599        updateCpuStats();
3600        checkTime(startTime, "startProcess: done updating cpu stats");
3601
3602        try {
3603            try {
3604                final int userId = UserHandle.getUserId(app.uid);
3605                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3606            } catch (RemoteException e) {
3607                throw e.rethrowAsRuntimeException();
3608            }
3609
3610            int uid = app.uid;
3611            int[] gids = null;
3612            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3613            if (!app.isolated) {
3614                int[] permGids = null;
3615                try {
3616                    checkTime(startTime, "startProcess: getting gids from package manager");
3617                    final IPackageManager pm = AppGlobals.getPackageManager();
3618                    permGids = pm.getPackageGids(app.info.packageName,
3619                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3620                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3621                            StorageManagerInternal.class);
3622                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3623                            app.info.packageName);
3624                } catch (RemoteException e) {
3625                    throw e.rethrowAsRuntimeException();
3626                }
3627
3628                /*
3629                 * Add shared application and profile GIDs so applications can share some
3630                 * resources like shared libraries and access user-wide resources
3631                 */
3632                if (ArrayUtils.isEmpty(permGids)) {
3633                    gids = new int[3];
3634                } else {
3635                    gids = new int[permGids.length + 3];
3636                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3637                }
3638                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3639                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3640                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3641            }
3642            checkTime(startTime, "startProcess: building args");
3643            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3644                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3645                        && mTopComponent != null
3646                        && app.processName.equals(mTopComponent.getPackageName())) {
3647                    uid = 0;
3648                }
3649                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3650                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3651                    uid = 0;
3652                }
3653            }
3654            int debugFlags = 0;
3655            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3656                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3657                // Also turn on CheckJNI for debuggable apps. It's quite
3658                // awkward to turn on otherwise.
3659                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3660            }
3661            // Run the app in safe mode if its manifest requests so or the
3662            // system is booted in safe mode.
3663            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3664                mSafeMode == true) {
3665                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3666            }
3667            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3668                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3669            }
3670            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3671            if ("true".equals(genDebugInfoProperty)) {
3672                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3673            }
3674            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3675                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3676            }
3677            if ("1".equals(SystemProperties.get("debug.assert"))) {
3678                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3679            }
3680            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3681                // Enable all debug flags required by the native debugger.
3682                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3683                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3684                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3685                mNativeDebuggingApp = null;
3686            }
3687
3688            String invokeWith = null;
3689            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3690                // Debuggable apps may include a wrapper script with their library directory.
3691                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3692                if (new File(wrapperFileName).exists()) {
3693                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3694                }
3695            }
3696
3697            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3698            if (requiredAbi == null) {
3699                requiredAbi = Build.SUPPORTED_ABIS[0];
3700            }
3701
3702            String instructionSet = null;
3703            if (app.info.primaryCpuAbi != null) {
3704                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3705            }
3706
3707            app.gids = gids;
3708            app.requiredAbi = requiredAbi;
3709            app.instructionSet = instructionSet;
3710
3711            // Start the process.  It will either succeed and return a result containing
3712            // the PID of the new process, or else throw a RuntimeException.
3713            boolean isActivityProcess = (entryPoint == null);
3714            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3715            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3716                    app.processName);
3717            checkTime(startTime, "startProcess: asking zygote to start proc");
3718            Process.ProcessStartResult startResult;
3719            if (hostingType.equals("webview_service")) {
3720                startResult = Process.startWebView(entryPoint,
3721                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3722                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3723                        app.info.dataDir, null, entryPointArgs);
3724            } else {
3725                startResult = Process.start(entryPoint,
3726                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3727                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3728                        app.info.dataDir, invokeWith, entryPointArgs);
3729            }
3730            checkTime(startTime, "startProcess: returned from zygote!");
3731            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3732
3733            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3734            checkTime(startTime, "startProcess: done updating battery stats");
3735
3736            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3737                    UserHandle.getUserId(uid), startResult.pid, uid,
3738                    app.processName, hostingType,
3739                    hostingNameStr != null ? hostingNameStr : "");
3740
3741            try {
3742                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3743                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3744            } catch (RemoteException ex) {
3745                // Ignore
3746            }
3747
3748            if (app.persistent) {
3749                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3750            }
3751
3752            checkTime(startTime, "startProcess: building log message");
3753            StringBuilder buf = mStringBuilder;
3754            buf.setLength(0);
3755            buf.append("Start proc ");
3756            buf.append(startResult.pid);
3757            buf.append(':');
3758            buf.append(app.processName);
3759            buf.append('/');
3760            UserHandle.formatUid(buf, uid);
3761            if (!isActivityProcess) {
3762                buf.append(" [");
3763                buf.append(entryPoint);
3764                buf.append("]");
3765            }
3766            buf.append(" for ");
3767            buf.append(hostingType);
3768            if (hostingNameStr != null) {
3769                buf.append(" ");
3770                buf.append(hostingNameStr);
3771            }
3772            Slog.i(TAG, buf.toString());
3773            app.setPid(startResult.pid);
3774            app.usingWrapper = startResult.usingWrapper;
3775            app.removed = false;
3776            app.killed = false;
3777            app.killedByAm = false;
3778            checkTime(startTime, "startProcess: starting to update pids map");
3779            ProcessRecord oldApp;
3780            synchronized (mPidsSelfLocked) {
3781                oldApp = mPidsSelfLocked.get(startResult.pid);
3782            }
3783            // If there is already an app occupying that pid that hasn't been cleaned up
3784            if (oldApp != null && !app.isolated) {
3785                // Clean up anything relating to this pid first
3786                Slog.w(TAG, "Reusing pid " + startResult.pid
3787                        + " while app is still mapped to it");
3788                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3789                        true /*replacingPid*/);
3790            }
3791            synchronized (mPidsSelfLocked) {
3792                this.mPidsSelfLocked.put(startResult.pid, app);
3793                if (isActivityProcess) {
3794                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3795                    msg.obj = app;
3796                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3797                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3798                }
3799            }
3800            checkTime(startTime, "startProcess: done updating pids map");
3801        } catch (RuntimeException e) {
3802            Slog.e(TAG, "Failure starting process " + app.processName, e);
3803
3804            // Something went very wrong while trying to start this process; one
3805            // common case is when the package is frozen due to an active
3806            // upgrade. To recover, clean up any active bookkeeping related to
3807            // starting this process. (We already invoked this method once when
3808            // the package was initially frozen through KILL_APPLICATION_MSG, so
3809            // it doesn't hurt to use it again.)
3810            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3811                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3812        }
3813    }
3814
3815    void updateUsageStats(ActivityRecord component, boolean resumed) {
3816        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3817                "updateUsageStats: comp=" + component + "res=" + resumed);
3818        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3819        if (resumed) {
3820            if (mUsageStatsService != null) {
3821                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3822                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3823            }
3824            synchronized (stats) {
3825                stats.noteActivityResumedLocked(component.app.uid);
3826            }
3827        } else {
3828            if (mUsageStatsService != null) {
3829                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3830                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3831            }
3832            synchronized (stats) {
3833                stats.noteActivityPausedLocked(component.app.uid);
3834            }
3835        }
3836    }
3837
3838    Intent getHomeIntent() {
3839        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3840        intent.setComponent(mTopComponent);
3841        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3842        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3843            intent.addCategory(Intent.CATEGORY_HOME);
3844        }
3845        return intent;
3846    }
3847
3848    boolean startHomeActivityLocked(int userId, String reason) {
3849        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3850                && mTopAction == null) {
3851            // We are running in factory test mode, but unable to find
3852            // the factory test app, so just sit around displaying the
3853            // error message and don't try to start anything.
3854            return false;
3855        }
3856        Intent intent = getHomeIntent();
3857        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3858        if (aInfo != null) {
3859            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3860            // Don't do this if the home app is currently being
3861            // instrumented.
3862            aInfo = new ActivityInfo(aInfo);
3863            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3864            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3865                    aInfo.applicationInfo.uid, true);
3866            if (app == null || app.instrumentationClass == null) {
3867                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3868                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3869            }
3870        } else {
3871            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3872        }
3873
3874        return true;
3875    }
3876
3877    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3878        ActivityInfo ai = null;
3879        ComponentName comp = intent.getComponent();
3880        try {
3881            if (comp != null) {
3882                // Factory test.
3883                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3884            } else {
3885                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3886                        intent,
3887                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3888                        flags, userId);
3889
3890                if (info != null) {
3891                    ai = info.activityInfo;
3892                }
3893            }
3894        } catch (RemoteException e) {
3895            // ignore
3896        }
3897
3898        return ai;
3899    }
3900
3901    /**
3902     * Starts the "new version setup screen" if appropriate.
3903     */
3904    void startSetupActivityLocked() {
3905        // Only do this once per boot.
3906        if (mCheckedForSetup) {
3907            return;
3908        }
3909
3910        // We will show this screen if the current one is a different
3911        // version than the last one shown, and we are not running in
3912        // low-level factory test mode.
3913        final ContentResolver resolver = mContext.getContentResolver();
3914        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3915                Settings.Global.getInt(resolver,
3916                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3917            mCheckedForSetup = true;
3918
3919            // See if we should be showing the platform update setup UI.
3920            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3921            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3922                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3923            if (!ris.isEmpty()) {
3924                final ResolveInfo ri = ris.get(0);
3925                String vers = ri.activityInfo.metaData != null
3926                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3927                        : null;
3928                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3929                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3930                            Intent.METADATA_SETUP_VERSION);
3931                }
3932                String lastVers = Settings.Secure.getString(
3933                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3934                if (vers != null && !vers.equals(lastVers)) {
3935                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3936                    intent.setComponent(new ComponentName(
3937                            ri.activityInfo.packageName, ri.activityInfo.name));
3938                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3939                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3940                            null, 0, 0, 0, null, false, false, null, null, null);
3941                }
3942            }
3943        }
3944    }
3945
3946    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3947        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3948    }
3949
3950    void enforceNotIsolatedCaller(String caller) {
3951        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3952            throw new SecurityException("Isolated process not allowed to call " + caller);
3953        }
3954    }
3955
3956    void enforceShellRestriction(String restriction, int userHandle) {
3957        if (Binder.getCallingUid() == Process.SHELL_UID) {
3958            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3959                throw new SecurityException("Shell does not have permission to access user "
3960                        + userHandle);
3961            }
3962        }
3963    }
3964
3965    @Override
3966    public int getFrontActivityScreenCompatMode() {
3967        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3968        synchronized (this) {
3969            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3970        }
3971    }
3972
3973    @Override
3974    public void setFrontActivityScreenCompatMode(int mode) {
3975        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3976                "setFrontActivityScreenCompatMode");
3977        synchronized (this) {
3978            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3979        }
3980    }
3981
3982    @Override
3983    public int getPackageScreenCompatMode(String packageName) {
3984        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3985        synchronized (this) {
3986            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3987        }
3988    }
3989
3990    @Override
3991    public void setPackageScreenCompatMode(String packageName, int mode) {
3992        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3993                "setPackageScreenCompatMode");
3994        synchronized (this) {
3995            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3996        }
3997    }
3998
3999    @Override
4000    public boolean getPackageAskScreenCompat(String packageName) {
4001        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4002        synchronized (this) {
4003            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4004        }
4005    }
4006
4007    @Override
4008    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4009        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4010                "setPackageAskScreenCompat");
4011        synchronized (this) {
4012            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4013        }
4014    }
4015
4016    private boolean hasUsageStatsPermission(String callingPackage) {
4017        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4018                Binder.getCallingUid(), callingPackage);
4019        if (mode == AppOpsManager.MODE_DEFAULT) {
4020            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4021                    == PackageManager.PERMISSION_GRANTED;
4022        }
4023        return mode == AppOpsManager.MODE_ALLOWED;
4024    }
4025
4026    @Override
4027    public int getPackageProcessState(String packageName, String callingPackage) {
4028        if (!hasUsageStatsPermission(callingPackage)) {
4029            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4030                    "getPackageProcessState");
4031        }
4032
4033        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4034        synchronized (this) {
4035            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4036                final ProcessRecord proc = mLruProcesses.get(i);
4037                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4038                        || procState > proc.setProcState) {
4039                    if (proc.pkgList.containsKey(packageName)) {
4040                        procState = proc.setProcState;
4041                        break;
4042                    }
4043                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
4044                        procState = proc.setProcState;
4045                    }
4046                }
4047            }
4048        }
4049        return procState;
4050    }
4051
4052    @Override
4053    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4054            throws RemoteException {
4055        synchronized (this) {
4056            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4057            if (app == null) {
4058                throw new IllegalArgumentException("Unknown process: " + process);
4059            }
4060            if (app.thread == null) {
4061                throw new IllegalArgumentException("Process has no app thread");
4062            }
4063            if (app.trimMemoryLevel >= level) {
4064                throw new IllegalArgumentException(
4065                        "Unable to set a higher trim level than current level");
4066            }
4067            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4068                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4069                throw new IllegalArgumentException("Unable to set a background trim level "
4070                    + "on a foreground process");
4071            }
4072            app.thread.scheduleTrimMemory(level);
4073            app.trimMemoryLevel = level;
4074            return true;
4075        }
4076    }
4077
4078    private void dispatchProcessesChanged() {
4079        int N;
4080        synchronized (this) {
4081            N = mPendingProcessChanges.size();
4082            if (mActiveProcessChanges.length < N) {
4083                mActiveProcessChanges = new ProcessChangeItem[N];
4084            }
4085            mPendingProcessChanges.toArray(mActiveProcessChanges);
4086            mPendingProcessChanges.clear();
4087            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4088                    "*** Delivering " + N + " process changes");
4089        }
4090
4091        int i = mProcessObservers.beginBroadcast();
4092        while (i > 0) {
4093            i--;
4094            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4095            if (observer != null) {
4096                try {
4097                    for (int j=0; j<N; j++) {
4098                        ProcessChangeItem item = mActiveProcessChanges[j];
4099                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4100                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4101                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4102                                    + item.uid + ": " + item.foregroundActivities);
4103                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4104                                    item.foregroundActivities);
4105                        }
4106                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4107                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4108                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4109                                    + ": " + item.processState);
4110                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4111                        }
4112                    }
4113                } catch (RemoteException e) {
4114                }
4115            }
4116        }
4117        mProcessObservers.finishBroadcast();
4118
4119        synchronized (this) {
4120            for (int j=0; j<N; j++) {
4121                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4122            }
4123        }
4124    }
4125
4126    private void dispatchProcessDied(int pid, int uid) {
4127        int i = mProcessObservers.beginBroadcast();
4128        while (i > 0) {
4129            i--;
4130            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4131            if (observer != null) {
4132                try {
4133                    observer.onProcessDied(pid, uid);
4134                } catch (RemoteException e) {
4135                }
4136            }
4137        }
4138        mProcessObservers.finishBroadcast();
4139    }
4140
4141    private void dispatchUidsChanged() {
4142        int N;
4143        synchronized (this) {
4144            N = mPendingUidChanges.size();
4145            if (mActiveUidChanges.length < N) {
4146                mActiveUidChanges = new UidRecord.ChangeItem[N];
4147            }
4148            for (int i=0; i<N; i++) {
4149                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4150                mActiveUidChanges[i] = change;
4151                if (change.uidRecord != null) {
4152                    change.uidRecord.pendingChange = null;
4153                    change.uidRecord = null;
4154                }
4155            }
4156            mPendingUidChanges.clear();
4157            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4158                    "*** Delivering " + N + " uid changes");
4159        }
4160
4161        int i = mUidObservers.beginBroadcast();
4162        while (i > 0) {
4163            i--;
4164            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4165            final UidObserverRegistration reg = (UidObserverRegistration)
4166                    mUidObservers.getBroadcastCookie(i);
4167            if (observer != null) {
4168                try {
4169                    for (int j=0; j<N; j++) {
4170                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4171                        final int change = item.change;
4172                        UidRecord validateUid = null;
4173                        if (VALIDATE_UID_STATES && i == 0) {
4174                            validateUid = mValidateUids.get(item.uid);
4175                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4176                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4177                                validateUid = new UidRecord(item.uid);
4178                                mValidateUids.put(item.uid, validateUid);
4179                            }
4180                        }
4181                        if (change == UidRecord.CHANGE_IDLE
4182                                || change == UidRecord.CHANGE_GONE_IDLE) {
4183                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4184                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4185                                        "UID idle uid=" + item.uid);
4186                                observer.onUidIdle(item.uid, item.ephemeral);
4187                            }
4188                            if (VALIDATE_UID_STATES && i == 0) {
4189                                if (validateUid != null) {
4190                                    validateUid.idle = true;
4191                                }
4192                            }
4193                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4194                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4195                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4196                                        "UID active uid=" + item.uid);
4197                                observer.onUidActive(item.uid);
4198                            }
4199                            if (VALIDATE_UID_STATES && i == 0) {
4200                                validateUid.idle = false;
4201                            }
4202                        }
4203                        if (change == UidRecord.CHANGE_GONE
4204                                || change == UidRecord.CHANGE_GONE_IDLE) {
4205                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4206                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4207                                        "UID gone uid=" + item.uid);
4208                                observer.onUidGone(item.uid, item.ephemeral);
4209                            }
4210                            if (reg.lastProcStates != null) {
4211                                reg.lastProcStates.delete(item.uid);
4212                            }
4213                            if (VALIDATE_UID_STATES && i == 0) {
4214                                if (validateUid != null) {
4215                                    mValidateUids.remove(item.uid);
4216                                }
4217                            }
4218                        } else {
4219                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4220                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4221                                        "UID CHANGED uid=" + item.uid
4222                                                + ": " + item.processState);
4223                                boolean doReport = true;
4224                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4225                                    final int lastState = reg.lastProcStates.get(item.uid,
4226                                            ActivityManager.PROCESS_STATE_UNKNOWN);
4227                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4228                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
4229                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
4230                                        doReport = lastAboveCut != newAboveCut;
4231                                    } else {
4232                                        doReport = item.processState
4233                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
4234                                    }
4235                                }
4236                                if (doReport) {
4237                                    if (reg.lastProcStates != null) {
4238                                        reg.lastProcStates.put(item.uid, item.processState);
4239                                    }
4240                                    observer.onUidStateChanged(item.uid, item.processState);
4241                                }
4242                            }
4243                            if (VALIDATE_UID_STATES && i == 0) {
4244                                validateUid.curProcState = validateUid.setProcState
4245                                        = item.processState;
4246                            }
4247                        }
4248                    }
4249                } catch (RemoteException e) {
4250                }
4251            }
4252        }
4253        mUidObservers.finishBroadcast();
4254
4255        synchronized (this) {
4256            for (int j=0; j<N; j++) {
4257                mAvailUidChanges.add(mActiveUidChanges[j]);
4258            }
4259        }
4260    }
4261
4262    @Override
4263    public final int startActivity(IApplicationThread caller, String callingPackage,
4264            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4265            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4266        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4267                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4268                UserHandle.getCallingUserId());
4269    }
4270
4271    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4272        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4273        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4274                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4275                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4276
4277        // TODO: Switch to user app stacks here.
4278        String mimeType = intent.getType();
4279        final Uri data = intent.getData();
4280        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4281            mimeType = getProviderMimeType(data, userId);
4282        }
4283        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4284
4285        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4286        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4287                null, 0, 0, null, null, null, null, false, userId, container, null);
4288    }
4289
4290    @Override
4291    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4292            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4293            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4294        enforceNotIsolatedCaller("startActivity");
4295        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4296                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4297        // TODO: Switch to user app stacks here.
4298        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4299                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4300                profilerInfo, null, null, bOptions, false, userId, null, null);
4301    }
4302
4303    @Override
4304    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4305            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4306            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4307            int userId) {
4308
4309        // This is very dangerous -- it allows you to perform a start activity (including
4310        // permission grants) as any app that may launch one of your own activities.  So
4311        // we will only allow this to be done from activities that are part of the core framework,
4312        // and then only when they are running as the system.
4313        final ActivityRecord sourceRecord;
4314        final int targetUid;
4315        final String targetPackage;
4316        synchronized (this) {
4317            if (resultTo == null) {
4318                throw new SecurityException("Must be called from an activity");
4319            }
4320            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4321            if (sourceRecord == null) {
4322                throw new SecurityException("Called with bad activity token: " + resultTo);
4323            }
4324            if (!sourceRecord.info.packageName.equals("android")) {
4325                throw new SecurityException(
4326                        "Must be called from an activity that is declared in the android package");
4327            }
4328            if (sourceRecord.app == null) {
4329                throw new SecurityException("Called without a process attached to activity");
4330            }
4331            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4332                // This is still okay, as long as this activity is running under the
4333                // uid of the original calling activity.
4334                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4335                    throw new SecurityException(
4336                            "Calling activity in uid " + sourceRecord.app.uid
4337                                    + " must be system uid or original calling uid "
4338                                    + sourceRecord.launchedFromUid);
4339                }
4340            }
4341            if (ignoreTargetSecurity) {
4342                if (intent.getComponent() == null) {
4343                    throw new SecurityException(
4344                            "Component must be specified with ignoreTargetSecurity");
4345                }
4346                if (intent.getSelector() != null) {
4347                    throw new SecurityException(
4348                            "Selector not allowed with ignoreTargetSecurity");
4349                }
4350            }
4351            targetUid = sourceRecord.launchedFromUid;
4352            targetPackage = sourceRecord.launchedFromPackage;
4353        }
4354
4355        if (userId == UserHandle.USER_NULL) {
4356            userId = UserHandle.getUserId(sourceRecord.app.uid);
4357        }
4358
4359        // TODO: Switch to user app stacks here.
4360        try {
4361            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4362                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4363                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4364            return ret;
4365        } catch (SecurityException e) {
4366            // XXX need to figure out how to propagate to original app.
4367            // A SecurityException here is generally actually a fault of the original
4368            // calling activity (such as a fairly granting permissions), so propagate it
4369            // back to them.
4370            /*
4371            StringBuilder msg = new StringBuilder();
4372            msg.append("While launching");
4373            msg.append(intent.toString());
4374            msg.append(": ");
4375            msg.append(e.getMessage());
4376            */
4377            throw e;
4378        }
4379    }
4380
4381    @Override
4382    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4383            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4384            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4385        enforceNotIsolatedCaller("startActivityAndWait");
4386        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4387                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4388        WaitResult res = new WaitResult();
4389        // TODO: Switch to user app stacks here.
4390        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4391                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4392                bOptions, false, userId, null, null);
4393        return res;
4394    }
4395
4396    @Override
4397    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4398            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4399            int startFlags, Configuration config, Bundle bOptions, int userId) {
4400        enforceNotIsolatedCaller("startActivityWithConfig");
4401        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4402                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4403        // TODO: Switch to user app stacks here.
4404        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4405                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4406                null, null, config, bOptions, false, userId, null, null);
4407        return ret;
4408    }
4409
4410    @Override
4411    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4412            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4413            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4414            throws TransactionTooLargeException {
4415        enforceNotIsolatedCaller("startActivityIntentSender");
4416        // Refuse possible leaked file descriptors
4417        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4418            throw new IllegalArgumentException("File descriptors passed in Intent");
4419        }
4420
4421        IIntentSender sender = intent.getTarget();
4422        if (!(sender instanceof PendingIntentRecord)) {
4423            throw new IllegalArgumentException("Bad PendingIntent object");
4424        }
4425
4426        PendingIntentRecord pir = (PendingIntentRecord)sender;
4427
4428        synchronized (this) {
4429            // If this is coming from the currently resumed activity, it is
4430            // effectively saying that app switches are allowed at this point.
4431            final ActivityStack stack = getFocusedStack();
4432            if (stack.mResumedActivity != null &&
4433                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4434                mAppSwitchesAllowedTime = 0;
4435            }
4436        }
4437        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4438                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4439        return ret;
4440    }
4441
4442    @Override
4443    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4444            Intent intent, String resolvedType, IVoiceInteractionSession session,
4445            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4446            Bundle bOptions, int userId) {
4447        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4448                != PackageManager.PERMISSION_GRANTED) {
4449            String msg = "Permission Denial: startVoiceActivity() from pid="
4450                    + Binder.getCallingPid()
4451                    + ", uid=" + Binder.getCallingUid()
4452                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4453            Slog.w(TAG, msg);
4454            throw new SecurityException(msg);
4455        }
4456        if (session == null || interactor == null) {
4457            throw new NullPointerException("null session or interactor");
4458        }
4459        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4460                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4461        // TODO: Switch to user app stacks here.
4462        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4463                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4464                null, bOptions, false, userId, null, null);
4465    }
4466
4467    @Override
4468    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4469            throws RemoteException {
4470        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4471        synchronized (this) {
4472            ActivityRecord activity = getFocusedStack().topActivity();
4473            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4474                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4475            }
4476            if (mRunningVoice != null || activity.task.voiceSession != null
4477                    || activity.voiceSession != null) {
4478                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4479                return;
4480            }
4481            if (activity.pendingVoiceInteractionStart) {
4482                Slog.w(TAG, "Pending start of voice interaction already.");
4483                return;
4484            }
4485            activity.pendingVoiceInteractionStart = true;
4486        }
4487        LocalServices.getService(VoiceInteractionManagerInternal.class)
4488                .startLocalVoiceInteraction(callingActivity, options);
4489    }
4490
4491    @Override
4492    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4493        LocalServices.getService(VoiceInteractionManagerInternal.class)
4494                .stopLocalVoiceInteraction(callingActivity);
4495    }
4496
4497    @Override
4498    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4499        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4500                .supportsLocalVoiceInteraction();
4501    }
4502
4503    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4504            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4505        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4506        if (activityToCallback == null) return;
4507        activityToCallback.setVoiceSessionLocked(voiceSession);
4508
4509        // Inform the activity
4510        try {
4511            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4512                    voiceInteractor);
4513            long token = Binder.clearCallingIdentity();
4514            try {
4515                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4516            } finally {
4517                Binder.restoreCallingIdentity(token);
4518            }
4519            // TODO: VI Should we cache the activity so that it's easier to find later
4520            // rather than scan through all the stacks and activities?
4521        } catch (RemoteException re) {
4522            activityToCallback.clearVoiceSessionLocked();
4523            // TODO: VI Should this terminate the voice session?
4524        }
4525    }
4526
4527    @Override
4528    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4529        synchronized (this) {
4530            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4531                if (keepAwake) {
4532                    mVoiceWakeLock.acquire();
4533                } else {
4534                    mVoiceWakeLock.release();
4535                }
4536            }
4537        }
4538    }
4539
4540    @Override
4541    public boolean startNextMatchingActivity(IBinder callingActivity,
4542            Intent intent, Bundle bOptions) {
4543        // Refuse possible leaked file descriptors
4544        if (intent != null && intent.hasFileDescriptors() == true) {
4545            throw new IllegalArgumentException("File descriptors passed in Intent");
4546        }
4547        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4548
4549        synchronized (this) {
4550            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4551            if (r == null) {
4552                ActivityOptions.abort(options);
4553                return false;
4554            }
4555            if (r.app == null || r.app.thread == null) {
4556                // The caller is not running...  d'oh!
4557                ActivityOptions.abort(options);
4558                return false;
4559            }
4560            intent = new Intent(intent);
4561            // The caller is not allowed to change the data.
4562            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4563            // And we are resetting to find the next component...
4564            intent.setComponent(null);
4565
4566            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4567
4568            ActivityInfo aInfo = null;
4569            try {
4570                List<ResolveInfo> resolves =
4571                    AppGlobals.getPackageManager().queryIntentActivities(
4572                            intent, r.resolvedType,
4573                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4574                            UserHandle.getCallingUserId()).getList();
4575
4576                // Look for the original activity in the list...
4577                final int N = resolves != null ? resolves.size() : 0;
4578                for (int i=0; i<N; i++) {
4579                    ResolveInfo rInfo = resolves.get(i);
4580                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4581                            && rInfo.activityInfo.name.equals(r.info.name)) {
4582                        // We found the current one...  the next matching is
4583                        // after it.
4584                        i++;
4585                        if (i<N) {
4586                            aInfo = resolves.get(i).activityInfo;
4587                        }
4588                        if (debug) {
4589                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4590                                    + "/" + r.info.name);
4591                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4592                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4593                        }
4594                        break;
4595                    }
4596                }
4597            } catch (RemoteException e) {
4598            }
4599
4600            if (aInfo == null) {
4601                // Nobody who is next!
4602                ActivityOptions.abort(options);
4603                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4604                return false;
4605            }
4606
4607            intent.setComponent(new ComponentName(
4608                    aInfo.applicationInfo.packageName, aInfo.name));
4609            intent.setFlags(intent.getFlags()&~(
4610                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4611                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4612                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4613                    Intent.FLAG_ACTIVITY_NEW_TASK));
4614
4615            // Okay now we need to start the new activity, replacing the
4616            // currently running activity.  This is a little tricky because
4617            // we want to start the new one as if the current one is finished,
4618            // but not finish the current one first so that there is no flicker.
4619            // And thus...
4620            final boolean wasFinishing = r.finishing;
4621            r.finishing = true;
4622
4623            // Propagate reply information over to the new activity.
4624            final ActivityRecord resultTo = r.resultTo;
4625            final String resultWho = r.resultWho;
4626            final int requestCode = r.requestCode;
4627            r.resultTo = null;
4628            if (resultTo != null) {
4629                resultTo.removeResultsLocked(r, resultWho, requestCode);
4630            }
4631
4632            final long origId = Binder.clearCallingIdentity();
4633            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4634                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4635                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4636                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4637                    false, false, null, null, null);
4638            Binder.restoreCallingIdentity(origId);
4639
4640            r.finishing = wasFinishing;
4641            if (res != ActivityManager.START_SUCCESS) {
4642                return false;
4643            }
4644            return true;
4645        }
4646    }
4647
4648    @Override
4649    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4650        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4651            String msg = "Permission Denial: startActivityFromRecents called without " +
4652                    START_TASKS_FROM_RECENTS;
4653            Slog.w(TAG, msg);
4654            throw new SecurityException(msg);
4655        }
4656        final long origId = Binder.clearCallingIdentity();
4657        try {
4658            synchronized (this) {
4659                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4660            }
4661        } finally {
4662            Binder.restoreCallingIdentity(origId);
4663        }
4664    }
4665
4666    final int startActivityInPackage(int uid, String callingPackage,
4667            Intent intent, String resolvedType, IBinder resultTo,
4668            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4669            IActivityContainer container, TaskRecord inTask) {
4670
4671        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4672                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4673
4674        // TODO: Switch to user app stacks here.
4675        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4676                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4677                null, null, null, bOptions, false, userId, container, inTask);
4678        return ret;
4679    }
4680
4681    @Override
4682    public final int startActivities(IApplicationThread caller, String callingPackage,
4683            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4684            int userId) {
4685        enforceNotIsolatedCaller("startActivities");
4686        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4687                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4688        // TODO: Switch to user app stacks here.
4689        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4690                resolvedTypes, resultTo, bOptions, userId);
4691        return ret;
4692    }
4693
4694    final int startActivitiesInPackage(int uid, String callingPackage,
4695            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4696            Bundle bOptions, int userId) {
4697
4698        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4699                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4700        // TODO: Switch to user app stacks here.
4701        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4702                resultTo, bOptions, userId);
4703        return ret;
4704    }
4705
4706    @Override
4707    public void reportActivityFullyDrawn(IBinder token) {
4708        synchronized (this) {
4709            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4710            if (r == null) {
4711                return;
4712            }
4713            r.reportFullyDrawnLocked();
4714        }
4715    }
4716
4717    @Override
4718    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4719        synchronized (this) {
4720            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4721            if (r == null) {
4722                return;
4723            }
4724            final long origId = Binder.clearCallingIdentity();
4725            try {
4726                r.setRequestedOrientation(requestedOrientation);
4727            } finally {
4728                Binder.restoreCallingIdentity(origId);
4729            }
4730        }
4731    }
4732
4733    @Override
4734    public int getRequestedOrientation(IBinder token) {
4735        synchronized (this) {
4736            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4737            if (r == null) {
4738                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4739            }
4740            return mWindowManager.getAppOrientation(r.appToken);
4741        }
4742    }
4743
4744    @Override
4745    public final void requestActivityRelaunch(IBinder token) {
4746        synchronized(this) {
4747            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4748            if (r == null) {
4749                return;
4750            }
4751            final long origId = Binder.clearCallingIdentity();
4752            try {
4753                r.forceNewConfig = true;
4754                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4755                        false /* preserveWindow */);
4756            } finally {
4757                Binder.restoreCallingIdentity(origId);
4758            }
4759        }
4760    }
4761
4762    /**
4763     * This is the internal entry point for handling Activity.finish().
4764     *
4765     * @param token The Binder token referencing the Activity we want to finish.
4766     * @param resultCode Result code, if any, from this Activity.
4767     * @param resultData Result data (Intent), if any, from this Activity.
4768     * @param finishTask Whether to finish the task associated with this Activity.
4769     *
4770     * @return Returns true if the activity successfully finished, or false if it is still running.
4771     */
4772    @Override
4773    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4774            int finishTask) {
4775        // Refuse possible leaked file descriptors
4776        if (resultData != null && resultData.hasFileDescriptors() == true) {
4777            throw new IllegalArgumentException("File descriptors passed in Intent");
4778        }
4779
4780        synchronized(this) {
4781            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4782            if (r == null) {
4783                return true;
4784            }
4785            // Keep track of the root activity of the task before we finish it
4786            TaskRecord tr = r.task;
4787            ActivityRecord rootR = tr.getRootActivity();
4788            if (rootR == null) {
4789                Slog.w(TAG, "Finishing task with all activities already finished");
4790            }
4791            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4792            // finish.
4793            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4794                    mStackSupervisor.isLastLockedTask(tr)) {
4795                Slog.i(TAG, "Not finishing task in lock task mode");
4796                mStackSupervisor.showLockTaskToast();
4797                return false;
4798            }
4799            if (mController != null) {
4800                // Find the first activity that is not finishing.
4801                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4802                if (next != null) {
4803                    // ask watcher if this is allowed
4804                    boolean resumeOK = true;
4805                    try {
4806                        resumeOK = mController.activityResuming(next.packageName);
4807                    } catch (RemoteException e) {
4808                        mController = null;
4809                        Watchdog.getInstance().setActivityController(null);
4810                    }
4811
4812                    if (!resumeOK) {
4813                        Slog.i(TAG, "Not finishing activity because controller resumed");
4814                        return false;
4815                    }
4816                }
4817            }
4818            final long origId = Binder.clearCallingIdentity();
4819            try {
4820                boolean res;
4821                final boolean finishWithRootActivity =
4822                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4823                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4824                        || (finishWithRootActivity && r == rootR)) {
4825                    // If requested, remove the task that is associated to this activity only if it
4826                    // was the root activity in the task. The result code and data is ignored
4827                    // because we don't support returning them across task boundaries. Also, to
4828                    // keep backwards compatibility we remove the task from recents when finishing
4829                    // task with root activity.
4830                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4831                    if (!res) {
4832                        Slog.i(TAG, "Removing task failed to finish activity");
4833                    }
4834                } else {
4835                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4836                            resultData, "app-request", true);
4837                    if (!res) {
4838                        Slog.i(TAG, "Failed to finish by app-request");
4839                    }
4840                }
4841                return res;
4842            } finally {
4843                Binder.restoreCallingIdentity(origId);
4844            }
4845        }
4846    }
4847
4848    @Override
4849    public final void finishHeavyWeightApp() {
4850        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4851                != PackageManager.PERMISSION_GRANTED) {
4852            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4853                    + Binder.getCallingPid()
4854                    + ", uid=" + Binder.getCallingUid()
4855                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4856            Slog.w(TAG, msg);
4857            throw new SecurityException(msg);
4858        }
4859
4860        synchronized(this) {
4861            if (mHeavyWeightProcess == null) {
4862                return;
4863            }
4864
4865            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4866            for (int i = 0; i < activities.size(); i++) {
4867                ActivityRecord r = activities.get(i);
4868                if (!r.finishing && r.isInStackLocked()) {
4869                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4870                            null, "finish-heavy", true);
4871                }
4872            }
4873
4874            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4875                    mHeavyWeightProcess.userId, 0));
4876            mHeavyWeightProcess = null;
4877        }
4878    }
4879
4880    @Override
4881    public void crashApplication(int uid, int initialPid, String packageName,
4882            String message) {
4883        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4884                != PackageManager.PERMISSION_GRANTED) {
4885            String msg = "Permission Denial: crashApplication() from pid="
4886                    + Binder.getCallingPid()
4887                    + ", uid=" + Binder.getCallingUid()
4888                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4889            Slog.w(TAG, msg);
4890            throw new SecurityException(msg);
4891        }
4892
4893        synchronized(this) {
4894            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4895        }
4896    }
4897
4898    @Override
4899    public final void finishSubActivity(IBinder token, String resultWho,
4900            int requestCode) {
4901        synchronized(this) {
4902            final long origId = Binder.clearCallingIdentity();
4903            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4904            if (r != null) {
4905                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4906            }
4907            Binder.restoreCallingIdentity(origId);
4908        }
4909    }
4910
4911    @Override
4912    public boolean finishActivityAffinity(IBinder token) {
4913        synchronized(this) {
4914            final long origId = Binder.clearCallingIdentity();
4915            try {
4916                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4917                if (r == null) {
4918                    return false;
4919                }
4920
4921                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4922                // can finish.
4923                final TaskRecord task = r.task;
4924                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4925                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4926                    mStackSupervisor.showLockTaskToast();
4927                    return false;
4928                }
4929                return task.getStack().finishActivityAffinityLocked(r);
4930            } finally {
4931                Binder.restoreCallingIdentity(origId);
4932            }
4933        }
4934    }
4935
4936    @Override
4937    public void finishVoiceTask(IVoiceInteractionSession session) {
4938        synchronized (this) {
4939            final long origId = Binder.clearCallingIdentity();
4940            try {
4941                // TODO: VI Consider treating local voice interactions and voice tasks
4942                // differently here
4943                mStackSupervisor.finishVoiceTask(session);
4944            } finally {
4945                Binder.restoreCallingIdentity(origId);
4946            }
4947        }
4948
4949    }
4950
4951    @Override
4952    public boolean releaseActivityInstance(IBinder token) {
4953        synchronized(this) {
4954            final long origId = Binder.clearCallingIdentity();
4955            try {
4956                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4957                if (r == null) {
4958                    return false;
4959                }
4960                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4961            } finally {
4962                Binder.restoreCallingIdentity(origId);
4963            }
4964        }
4965    }
4966
4967    @Override
4968    public void releaseSomeActivities(IApplicationThread appInt) {
4969        synchronized(this) {
4970            final long origId = Binder.clearCallingIdentity();
4971            try {
4972                ProcessRecord app = getRecordForAppLocked(appInt);
4973                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4974            } finally {
4975                Binder.restoreCallingIdentity(origId);
4976            }
4977        }
4978    }
4979
4980    @Override
4981    public boolean willActivityBeVisible(IBinder token) {
4982        synchronized(this) {
4983            ActivityStack stack = ActivityRecord.getStackLocked(token);
4984            if (stack != null) {
4985                return stack.willActivityBeVisibleLocked(token);
4986            }
4987            return false;
4988        }
4989    }
4990
4991    @Override
4992    public void overridePendingTransition(IBinder token, String packageName,
4993            int enterAnim, int exitAnim) {
4994        synchronized(this) {
4995            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4996            if (self == null) {
4997                return;
4998            }
4999
5000            final long origId = Binder.clearCallingIdentity();
5001
5002            if (self.state == ActivityState.RESUMED
5003                    || self.state == ActivityState.PAUSING) {
5004                mWindowManager.overridePendingAppTransition(packageName,
5005                        enterAnim, exitAnim, null);
5006            }
5007
5008            Binder.restoreCallingIdentity(origId);
5009        }
5010    }
5011
5012    /**
5013     * Main function for removing an existing process from the activity manager
5014     * as a result of that process going away.  Clears out all connections
5015     * to the process.
5016     */
5017    private final void handleAppDiedLocked(ProcessRecord app,
5018            boolean restarting, boolean allowRestart) {
5019        int pid = app.pid;
5020        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5021                false /*replacingPid*/);
5022        if (!kept && !restarting) {
5023            removeLruProcessLocked(app);
5024            if (pid > 0) {
5025                ProcessList.remove(pid);
5026            }
5027        }
5028
5029        if (mProfileProc == app) {
5030            clearProfilerLocked();
5031        }
5032
5033        // Remove this application's activities from active lists.
5034        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5035
5036        app.activities.clear();
5037
5038        if (app.instrumentationClass != null) {
5039            Slog.w(TAG, "Crash of app " + app.processName
5040                  + " running instrumentation " + app.instrumentationClass);
5041            Bundle info = new Bundle();
5042            info.putString("shortMsg", "Process crashed.");
5043            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5044        }
5045
5046        mWindowManager.deferSurfaceLayout();
5047        try {
5048            if (!restarting && hasVisibleActivities
5049                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5050                // If there was nothing to resume, and we are not already restarting this process, but
5051                // there is a visible activity that is hosted by the process...  then make sure all
5052                // visible activities are running, taking care of restarting this process.
5053                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5054            }
5055        } finally {
5056            mWindowManager.continueSurfaceLayout();
5057        }
5058    }
5059
5060    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5061        IBinder threadBinder = thread.asBinder();
5062        // Find the application record.
5063        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5064            ProcessRecord rec = mLruProcesses.get(i);
5065            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5066                return i;
5067            }
5068        }
5069        return -1;
5070    }
5071
5072    final ProcessRecord getRecordForAppLocked(
5073            IApplicationThread thread) {
5074        if (thread == null) {
5075            return null;
5076        }
5077
5078        int appIndex = getLRURecordIndexForAppLocked(thread);
5079        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5080    }
5081
5082    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5083        // If there are no longer any background processes running,
5084        // and the app that died was not running instrumentation,
5085        // then tell everyone we are now low on memory.
5086        boolean haveBg = false;
5087        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5088            ProcessRecord rec = mLruProcesses.get(i);
5089            if (rec.thread != null
5090                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5091                haveBg = true;
5092                break;
5093            }
5094        }
5095
5096        if (!haveBg) {
5097            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5098            if (doReport) {
5099                long now = SystemClock.uptimeMillis();
5100                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5101                    doReport = false;
5102                } else {
5103                    mLastMemUsageReportTime = now;
5104                }
5105            }
5106            final ArrayList<ProcessMemInfo> memInfos
5107                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5108            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5109            long now = SystemClock.uptimeMillis();
5110            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5111                ProcessRecord rec = mLruProcesses.get(i);
5112                if (rec == dyingProc || rec.thread == null) {
5113                    continue;
5114                }
5115                if (doReport) {
5116                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5117                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5118                }
5119                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5120                    // The low memory report is overriding any current
5121                    // state for a GC request.  Make sure to do
5122                    // heavy/important/visible/foreground processes first.
5123                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5124                        rec.lastRequestedGc = 0;
5125                    } else {
5126                        rec.lastRequestedGc = rec.lastLowMemory;
5127                    }
5128                    rec.reportLowMemory = true;
5129                    rec.lastLowMemory = now;
5130                    mProcessesToGc.remove(rec);
5131                    addProcessToGcListLocked(rec);
5132                }
5133            }
5134            if (doReport) {
5135                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5136                mHandler.sendMessage(msg);
5137            }
5138            scheduleAppGcsLocked();
5139        }
5140    }
5141
5142    final void appDiedLocked(ProcessRecord app) {
5143       appDiedLocked(app, app.pid, app.thread, false);
5144    }
5145
5146    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5147            boolean fromBinderDied) {
5148        // First check if this ProcessRecord is actually active for the pid.
5149        synchronized (mPidsSelfLocked) {
5150            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5151            if (curProc != app) {
5152                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5153                return;
5154            }
5155        }
5156
5157        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5158        synchronized (stats) {
5159            stats.noteProcessDiedLocked(app.info.uid, pid);
5160        }
5161
5162        if (!app.killed) {
5163            if (!fromBinderDied) {
5164                Process.killProcessQuiet(pid);
5165            }
5166            killProcessGroup(app.uid, pid);
5167            app.killed = true;
5168        }
5169
5170        // Clean up already done if the process has been re-started.
5171        if (app.pid == pid && app.thread != null &&
5172                app.thread.asBinder() == thread.asBinder()) {
5173            boolean doLowMem = app.instrumentationClass == null;
5174            boolean doOomAdj = doLowMem;
5175            if (!app.killedByAm) {
5176                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5177                        + ") has died");
5178                mAllowLowerMemLevel = true;
5179            } else {
5180                // Note that we always want to do oom adj to update our state with the
5181                // new number of procs.
5182                mAllowLowerMemLevel = false;
5183                doLowMem = false;
5184            }
5185            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5186            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5187                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5188            handleAppDiedLocked(app, false, true);
5189
5190            if (doOomAdj) {
5191                updateOomAdjLocked();
5192            }
5193            if (doLowMem) {
5194                doLowMemReportIfNeededLocked(app);
5195            }
5196        } else if (app.pid != pid) {
5197            // A new process has already been started.
5198            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5199                    + ") has died and restarted (pid " + app.pid + ").");
5200            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5201        } else if (DEBUG_PROCESSES) {
5202            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5203                    + thread.asBinder());
5204        }
5205    }
5206
5207    /**
5208     * If a stack trace dump file is configured, dump process stack traces.
5209     * @param clearTraces causes the dump file to be erased prior to the new
5210     *    traces being written, if true; when false, the new traces will be
5211     *    appended to any existing file content.
5212     * @param firstPids of dalvik VM processes to dump stack traces for first
5213     * @param lastPids of dalvik VM processes to dump stack traces for last
5214     * @param nativeProcs optional list of native process names to dump stack crawls
5215     * @return file containing stack traces, or null if no dump file is configured
5216     */
5217    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5218            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5219        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5220        if (tracesPath == null || tracesPath.length() == 0) {
5221            return null;
5222        }
5223
5224        File tracesFile = new File(tracesPath);
5225        try {
5226            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5227            tracesFile.createNewFile();
5228            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5229        } catch (IOException e) {
5230            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5231            return null;
5232        }
5233
5234        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5235        return tracesFile;
5236    }
5237
5238    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5239            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5240        // Use a FileObserver to detect when traces finish writing.
5241        // The order of traces is considered important to maintain for legibility.
5242        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5243            @Override
5244            public synchronized void onEvent(int event, String path) { notify(); }
5245        };
5246
5247        try {
5248            observer.startWatching();
5249
5250            // First collect all of the stacks of the most important pids.
5251            if (firstPids != null) {
5252                try {
5253                    int num = firstPids.size();
5254                    for (int i = 0; i < num; i++) {
5255                        synchronized (observer) {
5256                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5257                                    + firstPids.get(i));
5258                            final long sime = SystemClock.elapsedRealtime();
5259                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5260                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5261                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5262                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5263                        }
5264                    }
5265                } catch (InterruptedException e) {
5266                    Slog.wtf(TAG, e);
5267                }
5268            }
5269
5270            // Next collect the stacks of the native pids
5271            if (nativeProcs != null) {
5272                int[] pids = Process.getPidsForCommands(nativeProcs);
5273                if (pids != null) {
5274                    for (int pid : pids) {
5275                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5276                        final long sime = SystemClock.elapsedRealtime();
5277                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5278                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5279                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5280                    }
5281                }
5282            }
5283
5284            // Lastly, measure CPU usage.
5285            if (processCpuTracker != null) {
5286                processCpuTracker.init();
5287                System.gc();
5288                processCpuTracker.update();
5289                try {
5290                    synchronized (processCpuTracker) {
5291                        processCpuTracker.wait(500); // measure over 1/2 second.
5292                    }
5293                } catch (InterruptedException e) {
5294                }
5295                processCpuTracker.update();
5296
5297                // We'll take the stack crawls of just the top apps using CPU.
5298                final int N = processCpuTracker.countWorkingStats();
5299                int numProcs = 0;
5300                for (int i=0; i<N && numProcs<5; i++) {
5301                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5302                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5303                        numProcs++;
5304                        try {
5305                            synchronized (observer) {
5306                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5307                                        + stats.pid);
5308                                final long stime = SystemClock.elapsedRealtime();
5309                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5310                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5311                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5312                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5313                            }
5314                        } catch (InterruptedException e) {
5315                            Slog.wtf(TAG, e);
5316                        }
5317                    } else if (DEBUG_ANR) {
5318                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5319                                + stats.pid);
5320                    }
5321                }
5322            }
5323        } finally {
5324            observer.stopWatching();
5325        }
5326    }
5327
5328    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5329        if (true || IS_USER_BUILD) {
5330            return;
5331        }
5332        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5333        if (tracesPath == null || tracesPath.length() == 0) {
5334            return;
5335        }
5336
5337        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5338        StrictMode.allowThreadDiskWrites();
5339        try {
5340            final File tracesFile = new File(tracesPath);
5341            final File tracesDir = tracesFile.getParentFile();
5342            final File tracesTmp = new File(tracesDir, "__tmp__");
5343            try {
5344                if (tracesFile.exists()) {
5345                    tracesTmp.delete();
5346                    tracesFile.renameTo(tracesTmp);
5347                }
5348                StringBuilder sb = new StringBuilder();
5349                Time tobj = new Time();
5350                tobj.set(System.currentTimeMillis());
5351                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5352                sb.append(": ");
5353                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5354                sb.append(" since ");
5355                sb.append(msg);
5356                FileOutputStream fos = new FileOutputStream(tracesFile);
5357                fos.write(sb.toString().getBytes());
5358                if (app == null) {
5359                    fos.write("\n*** No application process!".getBytes());
5360                }
5361                fos.close();
5362                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5363            } catch (IOException e) {
5364                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5365                return;
5366            }
5367
5368            if (app != null) {
5369                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5370                firstPids.add(app.pid);
5371                dumpStackTraces(tracesPath, firstPids, null, null, null);
5372            }
5373
5374            File lastTracesFile = null;
5375            File curTracesFile = null;
5376            for (int i=9; i>=0; i--) {
5377                String name = String.format(Locale.US, "slow%02d.txt", i);
5378                curTracesFile = new File(tracesDir, name);
5379                if (curTracesFile.exists()) {
5380                    if (lastTracesFile != null) {
5381                        curTracesFile.renameTo(lastTracesFile);
5382                    } else {
5383                        curTracesFile.delete();
5384                    }
5385                }
5386                lastTracesFile = curTracesFile;
5387            }
5388            tracesFile.renameTo(curTracesFile);
5389            if (tracesTmp.exists()) {
5390                tracesTmp.renameTo(tracesFile);
5391            }
5392        } finally {
5393            StrictMode.setThreadPolicy(oldPolicy);
5394        }
5395    }
5396
5397    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5398        if (!mLaunchWarningShown) {
5399            mLaunchWarningShown = true;
5400            mUiHandler.post(new Runnable() {
5401                @Override
5402                public void run() {
5403                    synchronized (ActivityManagerService.this) {
5404                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5405                        d.show();
5406                        mUiHandler.postDelayed(new Runnable() {
5407                            @Override
5408                            public void run() {
5409                                synchronized (ActivityManagerService.this) {
5410                                    d.dismiss();
5411                                    mLaunchWarningShown = false;
5412                                }
5413                            }
5414                        }, 4000);
5415                    }
5416                }
5417            });
5418        }
5419    }
5420
5421    @Override
5422    public boolean clearApplicationUserData(final String packageName,
5423            final IPackageDataObserver observer, int userId) {
5424        enforceNotIsolatedCaller("clearApplicationUserData");
5425        int uid = Binder.getCallingUid();
5426        int pid = Binder.getCallingPid();
5427        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5428                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5429
5430
5431        long callingId = Binder.clearCallingIdentity();
5432        try {
5433            IPackageManager pm = AppGlobals.getPackageManager();
5434            int pkgUid = -1;
5435            synchronized(this) {
5436                if (getPackageManagerInternalLocked().isPackageDataProtected(
5437                        userId, packageName)) {
5438                    throw new SecurityException(
5439                            "Cannot clear data for a protected package: " + packageName);
5440                }
5441
5442                try {
5443                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5444                } catch (RemoteException e) {
5445                }
5446                if (pkgUid == -1) {
5447                    Slog.w(TAG, "Invalid packageName: " + packageName);
5448                    if (observer != null) {
5449                        try {
5450                            observer.onRemoveCompleted(packageName, false);
5451                        } catch (RemoteException e) {
5452                            Slog.i(TAG, "Observer no longer exists.");
5453                        }
5454                    }
5455                    return false;
5456                }
5457                if (uid == pkgUid || checkComponentPermission(
5458                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5459                        pid, uid, -1, true)
5460                        == PackageManager.PERMISSION_GRANTED) {
5461                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5462                } else {
5463                    throw new SecurityException("PID " + pid + " does not have permission "
5464                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5465                                    + " of package " + packageName);
5466                }
5467
5468                // Remove all tasks match the cleared application package and user
5469                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5470                    final TaskRecord tr = mRecentTasks.get(i);
5471                    final String taskPackageName =
5472                            tr.getBaseIntent().getComponent().getPackageName();
5473                    if (tr.userId != userId) continue;
5474                    if (!taskPackageName.equals(packageName)) continue;
5475                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5476                }
5477            }
5478
5479            final int pkgUidF = pkgUid;
5480            final int userIdF = userId;
5481            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5482                @Override
5483                public void onRemoveCompleted(String packageName, boolean succeeded)
5484                        throws RemoteException {
5485                    synchronized (ActivityManagerService.this) {
5486                        finishForceStopPackageLocked(packageName, pkgUidF);
5487                    }
5488
5489                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5490                            Uri.fromParts("package", packageName, null));
5491                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5492                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5493                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5494                            null, null, 0, null, null, null, null, false, false, userIdF);
5495
5496                    if (observer != null) {
5497                        observer.onRemoveCompleted(packageName, succeeded);
5498                    }
5499                }
5500            };
5501
5502            try {
5503                // Clear application user data
5504                pm.clearApplicationUserData(packageName, localObserver, userId);
5505
5506                synchronized(this) {
5507                    // Remove all permissions granted from/to this package
5508                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5509                }
5510
5511                // Remove all zen rules created by this package; revoke it's zen access.
5512                INotificationManager inm = NotificationManager.getService();
5513                inm.removeAutomaticZenRules(packageName);
5514                inm.setNotificationPolicyAccessGranted(packageName, false);
5515
5516            } catch (RemoteException e) {
5517            }
5518        } finally {
5519            Binder.restoreCallingIdentity(callingId);
5520        }
5521        return true;
5522    }
5523
5524    @Override
5525    public void killBackgroundProcesses(final String packageName, int userId) {
5526        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5527                != PackageManager.PERMISSION_GRANTED &&
5528                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5529                        != PackageManager.PERMISSION_GRANTED) {
5530            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5531                    + Binder.getCallingPid()
5532                    + ", uid=" + Binder.getCallingUid()
5533                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5534            Slog.w(TAG, msg);
5535            throw new SecurityException(msg);
5536        }
5537
5538        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5539                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5540        long callingId = Binder.clearCallingIdentity();
5541        try {
5542            IPackageManager pm = AppGlobals.getPackageManager();
5543            synchronized(this) {
5544                int appId = -1;
5545                try {
5546                    appId = UserHandle.getAppId(
5547                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5548                } catch (RemoteException e) {
5549                }
5550                if (appId == -1) {
5551                    Slog.w(TAG, "Invalid packageName: " + packageName);
5552                    return;
5553                }
5554                killPackageProcessesLocked(packageName, appId, userId,
5555                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5556            }
5557        } finally {
5558            Binder.restoreCallingIdentity(callingId);
5559        }
5560    }
5561
5562    @Override
5563    public void killAllBackgroundProcesses() {
5564        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5565                != PackageManager.PERMISSION_GRANTED) {
5566            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5567                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5568                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5569            Slog.w(TAG, msg);
5570            throw new SecurityException(msg);
5571        }
5572
5573        final long callingId = Binder.clearCallingIdentity();
5574        try {
5575            synchronized (this) {
5576                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5577                final int NP = mProcessNames.getMap().size();
5578                for (int ip = 0; ip < NP; ip++) {
5579                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5580                    final int NA = apps.size();
5581                    for (int ia = 0; ia < NA; ia++) {
5582                        final ProcessRecord app = apps.valueAt(ia);
5583                        if (app.persistent) {
5584                            // We don't kill persistent processes.
5585                            continue;
5586                        }
5587                        if (app.removed) {
5588                            procs.add(app);
5589                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5590                            app.removed = true;
5591                            procs.add(app);
5592                        }
5593                    }
5594                }
5595
5596                final int N = procs.size();
5597                for (int i = 0; i < N; i++) {
5598                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5599                }
5600
5601                mAllowLowerMemLevel = true;
5602
5603                updateOomAdjLocked();
5604                doLowMemReportIfNeededLocked(null);
5605            }
5606        } finally {
5607            Binder.restoreCallingIdentity(callingId);
5608        }
5609    }
5610
5611    /**
5612     * Kills all background processes, except those matching any of the
5613     * specified properties.
5614     *
5615     * @param minTargetSdk the target SDK version at or above which to preserve
5616     *                     processes, or {@code -1} to ignore the target SDK
5617     * @param maxProcState the process state at or below which to preserve
5618     *                     processes, or {@code -1} to ignore the process state
5619     */
5620    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5621        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5622                != PackageManager.PERMISSION_GRANTED) {
5623            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5624                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5625                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5626            Slog.w(TAG, msg);
5627            throw new SecurityException(msg);
5628        }
5629
5630        final long callingId = Binder.clearCallingIdentity();
5631        try {
5632            synchronized (this) {
5633                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5634                final int NP = mProcessNames.getMap().size();
5635                for (int ip = 0; ip < NP; ip++) {
5636                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5637                    final int NA = apps.size();
5638                    for (int ia = 0; ia < NA; ia++) {
5639                        final ProcessRecord app = apps.valueAt(ia);
5640                        if (app.removed) {
5641                            procs.add(app);
5642                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5643                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5644                            app.removed = true;
5645                            procs.add(app);
5646                        }
5647                    }
5648                }
5649
5650                final int N = procs.size();
5651                for (int i = 0; i < N; i++) {
5652                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5653                }
5654            }
5655        } finally {
5656            Binder.restoreCallingIdentity(callingId);
5657        }
5658    }
5659
5660    @Override
5661    public void forceStopPackage(final String packageName, int userId) {
5662        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5663                != PackageManager.PERMISSION_GRANTED) {
5664            String msg = "Permission Denial: forceStopPackage() from pid="
5665                    + Binder.getCallingPid()
5666                    + ", uid=" + Binder.getCallingUid()
5667                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5668            Slog.w(TAG, msg);
5669            throw new SecurityException(msg);
5670        }
5671        final int callingPid = Binder.getCallingPid();
5672        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5673                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5674        long callingId = Binder.clearCallingIdentity();
5675        try {
5676            IPackageManager pm = AppGlobals.getPackageManager();
5677            synchronized(this) {
5678                int[] users = userId == UserHandle.USER_ALL
5679                        ? mUserController.getUsers() : new int[] { userId };
5680                for (int user : users) {
5681                    int pkgUid = -1;
5682                    try {
5683                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5684                                user);
5685                    } catch (RemoteException e) {
5686                    }
5687                    if (pkgUid == -1) {
5688                        Slog.w(TAG, "Invalid packageName: " + packageName);
5689                        continue;
5690                    }
5691                    try {
5692                        pm.setPackageStoppedState(packageName, true, user);
5693                    } catch (RemoteException e) {
5694                    } catch (IllegalArgumentException e) {
5695                        Slog.w(TAG, "Failed trying to unstop package "
5696                                + packageName + ": " + e);
5697                    }
5698                    if (mUserController.isUserRunningLocked(user, 0)) {
5699                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5700                        finishForceStopPackageLocked(packageName, pkgUid);
5701                    }
5702                }
5703            }
5704        } finally {
5705            Binder.restoreCallingIdentity(callingId);
5706        }
5707    }
5708
5709    @Override
5710    public void addPackageDependency(String packageName) {
5711        synchronized (this) {
5712            int callingPid = Binder.getCallingPid();
5713            if (callingPid == Process.myPid()) {
5714                //  Yeah, um, no.
5715                return;
5716            }
5717            ProcessRecord proc;
5718            synchronized (mPidsSelfLocked) {
5719                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5720            }
5721            if (proc != null) {
5722                if (proc.pkgDeps == null) {
5723                    proc.pkgDeps = new ArraySet<String>(1);
5724                }
5725                proc.pkgDeps.add(packageName);
5726            }
5727        }
5728    }
5729
5730    /*
5731     * The pkg name and app id have to be specified.
5732     */
5733    @Override
5734    public void killApplication(String pkg, int appId, int userId, String reason) {
5735        if (pkg == null) {
5736            return;
5737        }
5738        // Make sure the uid is valid.
5739        if (appId < 0) {
5740            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5741            return;
5742        }
5743        int callerUid = Binder.getCallingUid();
5744        // Only the system server can kill an application
5745        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5746            // Post an aysnc message to kill the application
5747            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5748            msg.arg1 = appId;
5749            msg.arg2 = userId;
5750            Bundle bundle = new Bundle();
5751            bundle.putString("pkg", pkg);
5752            bundle.putString("reason", reason);
5753            msg.obj = bundle;
5754            mHandler.sendMessage(msg);
5755        } else {
5756            throw new SecurityException(callerUid + " cannot kill pkg: " +
5757                    pkg);
5758        }
5759    }
5760
5761    @Override
5762    public void closeSystemDialogs(String reason) {
5763        enforceNotIsolatedCaller("closeSystemDialogs");
5764
5765        final int pid = Binder.getCallingPid();
5766        final int uid = Binder.getCallingUid();
5767        final long origId = Binder.clearCallingIdentity();
5768        try {
5769            synchronized (this) {
5770                // Only allow this from foreground processes, so that background
5771                // applications can't abuse it to prevent system UI from being shown.
5772                if (uid >= Process.FIRST_APPLICATION_UID) {
5773                    ProcessRecord proc;
5774                    synchronized (mPidsSelfLocked) {
5775                        proc = mPidsSelfLocked.get(pid);
5776                    }
5777                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5778                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5779                                + " from background process " + proc);
5780                        return;
5781                    }
5782                }
5783                closeSystemDialogsLocked(reason);
5784            }
5785        } finally {
5786            Binder.restoreCallingIdentity(origId);
5787        }
5788    }
5789
5790    void closeSystemDialogsLocked(String reason) {
5791        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5792        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5793                | Intent.FLAG_RECEIVER_FOREGROUND);
5794        if (reason != null) {
5795            intent.putExtra("reason", reason);
5796        }
5797        mWindowManager.closeSystemDialogs(reason);
5798
5799        mStackSupervisor.closeSystemDialogsLocked();
5800
5801        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5802                AppOpsManager.OP_NONE, null, false, false,
5803                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5804    }
5805
5806    @Override
5807    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5808        enforceNotIsolatedCaller("getProcessMemoryInfo");
5809        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5810        for (int i=pids.length-1; i>=0; i--) {
5811            ProcessRecord proc;
5812            int oomAdj;
5813            synchronized (this) {
5814                synchronized (mPidsSelfLocked) {
5815                    proc = mPidsSelfLocked.get(pids[i]);
5816                    oomAdj = proc != null ? proc.setAdj : 0;
5817                }
5818            }
5819            infos[i] = new Debug.MemoryInfo();
5820            Debug.getMemoryInfo(pids[i], infos[i]);
5821            if (proc != null) {
5822                synchronized (this) {
5823                    if (proc.thread != null && proc.setAdj == oomAdj) {
5824                        // Record this for posterity if the process has been stable.
5825                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5826                                infos[i].getTotalUss(), false, proc.pkgList);
5827                    }
5828                }
5829            }
5830        }
5831        return infos;
5832    }
5833
5834    @Override
5835    public long[] getProcessPss(int[] pids) {
5836        enforceNotIsolatedCaller("getProcessPss");
5837        long[] pss = new long[pids.length];
5838        for (int i=pids.length-1; i>=0; i--) {
5839            ProcessRecord proc;
5840            int oomAdj;
5841            synchronized (this) {
5842                synchronized (mPidsSelfLocked) {
5843                    proc = mPidsSelfLocked.get(pids[i]);
5844                    oomAdj = proc != null ? proc.setAdj : 0;
5845                }
5846            }
5847            long[] tmpUss = new long[1];
5848            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5849            if (proc != null) {
5850                synchronized (this) {
5851                    if (proc.thread != null && proc.setAdj == oomAdj) {
5852                        // Record this for posterity if the process has been stable.
5853                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5854                    }
5855                }
5856            }
5857        }
5858        return pss;
5859    }
5860
5861    @Override
5862    public void killApplicationProcess(String processName, int uid) {
5863        if (processName == null) {
5864            return;
5865        }
5866
5867        int callerUid = Binder.getCallingUid();
5868        // Only the system server can kill an application
5869        if (callerUid == Process.SYSTEM_UID) {
5870            synchronized (this) {
5871                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5872                if (app != null && app.thread != null) {
5873                    try {
5874                        app.thread.scheduleSuicide();
5875                    } catch (RemoteException e) {
5876                        // If the other end already died, then our work here is done.
5877                    }
5878                } else {
5879                    Slog.w(TAG, "Process/uid not found attempting kill of "
5880                            + processName + " / " + uid);
5881                }
5882            }
5883        } else {
5884            throw new SecurityException(callerUid + " cannot kill app process: " +
5885                    processName);
5886        }
5887    }
5888
5889    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5890        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5891                false, true, false, false, UserHandle.getUserId(uid), reason);
5892    }
5893
5894    private void finishForceStopPackageLocked(final String packageName, int uid) {
5895        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5896                Uri.fromParts("package", packageName, null));
5897        if (!mProcessesReady) {
5898            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5899                    | Intent.FLAG_RECEIVER_FOREGROUND);
5900        }
5901        intent.putExtra(Intent.EXTRA_UID, uid);
5902        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5903        broadcastIntentLocked(null, null, intent,
5904                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5905                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5906    }
5907
5908
5909    private final boolean killPackageProcessesLocked(String packageName, int appId,
5910            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5911            boolean doit, boolean evenPersistent, String reason) {
5912        ArrayList<ProcessRecord> procs = new ArrayList<>();
5913
5914        // Remove all processes this package may have touched: all with the
5915        // same UID (except for the system or root user), and all whose name
5916        // matches the package name.
5917        final int NP = mProcessNames.getMap().size();
5918        for (int ip=0; ip<NP; ip++) {
5919            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5920            final int NA = apps.size();
5921            for (int ia=0; ia<NA; ia++) {
5922                ProcessRecord app = apps.valueAt(ia);
5923                if (app.persistent && !evenPersistent) {
5924                    // we don't kill persistent processes
5925                    continue;
5926                }
5927                if (app.removed) {
5928                    if (doit) {
5929                        procs.add(app);
5930                    }
5931                    continue;
5932                }
5933
5934                // Skip process if it doesn't meet our oom adj requirement.
5935                if (app.setAdj < minOomAdj) {
5936                    continue;
5937                }
5938
5939                // If no package is specified, we call all processes under the
5940                // give user id.
5941                if (packageName == null) {
5942                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5943                        continue;
5944                    }
5945                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5946                        continue;
5947                    }
5948                // Package has been specified, we want to hit all processes
5949                // that match it.  We need to qualify this by the processes
5950                // that are running under the specified app and user ID.
5951                } else {
5952                    final boolean isDep = app.pkgDeps != null
5953                            && app.pkgDeps.contains(packageName);
5954                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5955                        continue;
5956                    }
5957                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5958                        continue;
5959                    }
5960                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5961                        continue;
5962                    }
5963                }
5964
5965                // Process has passed all conditions, kill it!
5966                if (!doit) {
5967                    return true;
5968                }
5969                app.removed = true;
5970                procs.add(app);
5971            }
5972        }
5973
5974        int N = procs.size();
5975        for (int i=0; i<N; i++) {
5976            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5977        }
5978        updateOomAdjLocked();
5979        return N > 0;
5980    }
5981
5982    private void cleanupDisabledPackageComponentsLocked(
5983            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5984
5985        Set<String> disabledClasses = null;
5986        boolean packageDisabled = false;
5987        IPackageManager pm = AppGlobals.getPackageManager();
5988
5989        if (changedClasses == null) {
5990            // Nothing changed...
5991            return;
5992        }
5993
5994        // Determine enable/disable state of the package and its components.
5995        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5996        for (int i = changedClasses.length - 1; i >= 0; i--) {
5997            final String changedClass = changedClasses[i];
5998
5999            if (changedClass.equals(packageName)) {
6000                try {
6001                    // Entire package setting changed
6002                    enabled = pm.getApplicationEnabledSetting(packageName,
6003                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6004                } catch (Exception e) {
6005                    // No such package/component; probably racing with uninstall.  In any
6006                    // event it means we have nothing further to do here.
6007                    return;
6008                }
6009                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6010                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6011                if (packageDisabled) {
6012                    // Entire package is disabled.
6013                    // No need to continue to check component states.
6014                    disabledClasses = null;
6015                    break;
6016                }
6017            } else {
6018                try {
6019                    enabled = pm.getComponentEnabledSetting(
6020                            new ComponentName(packageName, changedClass),
6021                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6022                } catch (Exception e) {
6023                    // As above, probably racing with uninstall.
6024                    return;
6025                }
6026                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6027                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6028                    if (disabledClasses == null) {
6029                        disabledClasses = new ArraySet<>(changedClasses.length);
6030                    }
6031                    disabledClasses.add(changedClass);
6032                }
6033            }
6034        }
6035
6036        if (!packageDisabled && disabledClasses == null) {
6037            // Nothing to do here...
6038            return;
6039        }
6040
6041        // Clean-up disabled activities.
6042        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6043                packageName, disabledClasses, true, false, userId) && mBooted) {
6044            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6045            mStackSupervisor.scheduleIdleLocked();
6046        }
6047
6048        // Clean-up disabled tasks
6049        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6050
6051        // Clean-up disabled services.
6052        mServices.bringDownDisabledPackageServicesLocked(
6053                packageName, disabledClasses, userId, false, killProcess, true);
6054
6055        // Clean-up disabled providers.
6056        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6057        mProviderMap.collectPackageProvidersLocked(
6058                packageName, disabledClasses, true, false, userId, providers);
6059        for (int i = providers.size() - 1; i >= 0; i--) {
6060            removeDyingProviderLocked(null, providers.get(i), true);
6061        }
6062
6063        // Clean-up disabled broadcast receivers.
6064        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6065            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6066                    packageName, disabledClasses, userId, true);
6067        }
6068
6069    }
6070
6071    final boolean clearBroadcastQueueForUserLocked(int userId) {
6072        boolean didSomething = false;
6073        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6074            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6075                    null, null, userId, true);
6076        }
6077        return didSomething;
6078    }
6079
6080    final boolean forceStopPackageLocked(String packageName, int appId,
6081            boolean callerWillRestart, boolean purgeCache, boolean doit,
6082            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6083        int i;
6084
6085        if (userId == UserHandle.USER_ALL && packageName == null) {
6086            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6087        }
6088
6089        if (appId < 0 && packageName != null) {
6090            try {
6091                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6092                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6093            } catch (RemoteException e) {
6094            }
6095        }
6096
6097        if (doit) {
6098            if (packageName != null) {
6099                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6100                        + " user=" + userId + ": " + reason);
6101            } else {
6102                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6103            }
6104
6105            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6106        }
6107
6108        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6109                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6110                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6111
6112        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6113
6114        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6115                packageName, null, doit, evenPersistent, userId)) {
6116            if (!doit) {
6117                return true;
6118            }
6119            didSomething = true;
6120        }
6121
6122        if (mServices.bringDownDisabledPackageServicesLocked(
6123                packageName, null, userId, evenPersistent, true, doit)) {
6124            if (!doit) {
6125                return true;
6126            }
6127            didSomething = true;
6128        }
6129
6130        if (packageName == null) {
6131            // Remove all sticky broadcasts from this user.
6132            mStickyBroadcasts.remove(userId);
6133        }
6134
6135        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6136        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6137                userId, providers)) {
6138            if (!doit) {
6139                return true;
6140            }
6141            didSomething = true;
6142        }
6143        for (i = providers.size() - 1; i >= 0; i--) {
6144            removeDyingProviderLocked(null, providers.get(i), true);
6145        }
6146
6147        // Remove transient permissions granted from/to this package/user
6148        removeUriPermissionsForPackageLocked(packageName, userId, false);
6149
6150        if (doit) {
6151            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6152                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6153                        packageName, null, userId, doit);
6154            }
6155        }
6156
6157        if (packageName == null || uninstalling) {
6158            // Remove pending intents.  For now we only do this when force
6159            // stopping users, because we have some problems when doing this
6160            // for packages -- app widgets are not currently cleaned up for
6161            // such packages, so they can be left with bad pending intents.
6162            if (mIntentSenderRecords.size() > 0) {
6163                Iterator<WeakReference<PendingIntentRecord>> it
6164                        = mIntentSenderRecords.values().iterator();
6165                while (it.hasNext()) {
6166                    WeakReference<PendingIntentRecord> wpir = it.next();
6167                    if (wpir == null) {
6168                        it.remove();
6169                        continue;
6170                    }
6171                    PendingIntentRecord pir = wpir.get();
6172                    if (pir == null) {
6173                        it.remove();
6174                        continue;
6175                    }
6176                    if (packageName == null) {
6177                        // Stopping user, remove all objects for the user.
6178                        if (pir.key.userId != userId) {
6179                            // Not the same user, skip it.
6180                            continue;
6181                        }
6182                    } else {
6183                        if (UserHandle.getAppId(pir.uid) != appId) {
6184                            // Different app id, skip it.
6185                            continue;
6186                        }
6187                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6188                            // Different user, skip it.
6189                            continue;
6190                        }
6191                        if (!pir.key.packageName.equals(packageName)) {
6192                            // Different package, skip it.
6193                            continue;
6194                        }
6195                    }
6196                    if (!doit) {
6197                        return true;
6198                    }
6199                    didSomething = true;
6200                    it.remove();
6201                    pir.canceled = true;
6202                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6203                        pir.key.activity.pendingResults.remove(pir.ref);
6204                    }
6205                }
6206            }
6207        }
6208
6209        if (doit) {
6210            if (purgeCache && packageName != null) {
6211                AttributeCache ac = AttributeCache.instance();
6212                if (ac != null) {
6213                    ac.removePackage(packageName);
6214                }
6215            }
6216            if (mBooted) {
6217                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6218                mStackSupervisor.scheduleIdleLocked();
6219            }
6220        }
6221
6222        return didSomething;
6223    }
6224
6225    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6226        return removeProcessNameLocked(name, uid, null);
6227    }
6228
6229    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6230            final ProcessRecord expecting) {
6231        ProcessRecord old = mProcessNames.get(name, uid);
6232        // Only actually remove when the currently recorded value matches the
6233        // record that we expected; if it doesn't match then we raced with a
6234        // newly created process and we don't want to destroy the new one.
6235        if ((expecting == null) || (old == expecting)) {
6236            mProcessNames.remove(name, uid);
6237        }
6238        if (old != null && old.uidRecord != null) {
6239            old.uidRecord.numProcs--;
6240            if (old.uidRecord.numProcs == 0) {
6241                // No more processes using this uid, tell clients it is gone.
6242                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6243                        "No more processes in " + old.uidRecord);
6244                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6245                mActiveUids.remove(uid);
6246                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6247            }
6248            old.uidRecord = null;
6249        }
6250        mIsolatedProcesses.remove(uid);
6251        return old;
6252    }
6253
6254    private final void addProcessNameLocked(ProcessRecord proc) {
6255        // We shouldn't already have a process under this name, but just in case we
6256        // need to clean up whatever may be there now.
6257        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6258        if (old == proc && proc.persistent) {
6259            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6260            Slog.w(TAG, "Re-adding persistent process " + proc);
6261        } else if (old != null) {
6262            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6263        }
6264        UidRecord uidRec = mActiveUids.get(proc.uid);
6265        if (uidRec == null) {
6266            uidRec = new UidRecord(proc.uid);
6267            // This is the first appearance of the uid, report it now!
6268            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6269                    "Creating new process uid: " + uidRec);
6270            mActiveUids.put(proc.uid, uidRec);
6271            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6272            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6273        }
6274        proc.uidRecord = uidRec;
6275
6276        // Reset render thread tid if it was already set, so new process can set it again.
6277        proc.renderThreadTid = 0;
6278        uidRec.numProcs++;
6279        mProcessNames.put(proc.processName, proc.uid, proc);
6280        if (proc.isolated) {
6281            mIsolatedProcesses.put(proc.uid, proc);
6282        }
6283    }
6284
6285    boolean removeProcessLocked(ProcessRecord app,
6286            boolean callerWillRestart, boolean allowRestart, String reason) {
6287        final String name = app.processName;
6288        final int uid = app.uid;
6289        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6290            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6291
6292        ProcessRecord old = mProcessNames.get(name, uid);
6293        if (old != app) {
6294            // This process is no longer active, so nothing to do.
6295            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6296            return false;
6297        }
6298        removeProcessNameLocked(name, uid);
6299        if (mHeavyWeightProcess == app) {
6300            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6301                    mHeavyWeightProcess.userId, 0));
6302            mHeavyWeightProcess = null;
6303        }
6304        boolean needRestart = false;
6305        if (app.pid > 0 && app.pid != MY_PID) {
6306            int pid = app.pid;
6307            synchronized (mPidsSelfLocked) {
6308                mPidsSelfLocked.remove(pid);
6309                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6310            }
6311            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6312            if (app.isolated) {
6313                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6314            }
6315            boolean willRestart = false;
6316            if (app.persistent && !app.isolated) {
6317                if (!callerWillRestart) {
6318                    willRestart = true;
6319                } else {
6320                    needRestart = true;
6321                }
6322            }
6323            app.kill(reason, true);
6324            handleAppDiedLocked(app, willRestart, allowRestart);
6325            if (willRestart) {
6326                removeLruProcessLocked(app);
6327                addAppLocked(app.info, false, null /* ABI override */);
6328            }
6329        } else {
6330            mRemovedProcesses.add(app);
6331        }
6332
6333        return needRestart;
6334    }
6335
6336    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6337        cleanupAppInLaunchingProvidersLocked(app, true);
6338        removeProcessLocked(app, false, true, "timeout publishing content providers");
6339    }
6340
6341    private final void processStartTimedOutLocked(ProcessRecord app) {
6342        final int pid = app.pid;
6343        boolean gone = false;
6344        synchronized (mPidsSelfLocked) {
6345            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6346            if (knownApp != null && knownApp.thread == null) {
6347                mPidsSelfLocked.remove(pid);
6348                gone = true;
6349            }
6350        }
6351
6352        if (gone) {
6353            Slog.w(TAG, "Process " + app + " failed to attach");
6354            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6355                    pid, app.uid, app.processName);
6356            removeProcessNameLocked(app.processName, app.uid);
6357            if (mHeavyWeightProcess == app) {
6358                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6359                        mHeavyWeightProcess.userId, 0));
6360                mHeavyWeightProcess = null;
6361            }
6362            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6363            if (app.isolated) {
6364                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6365            }
6366            // Take care of any launching providers waiting for this process.
6367            cleanupAppInLaunchingProvidersLocked(app, true);
6368            // Take care of any services that are waiting for the process.
6369            mServices.processStartTimedOutLocked(app);
6370            app.kill("start timeout", true);
6371            removeLruProcessLocked(app);
6372            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6373                Slog.w(TAG, "Unattached app died before backup, skipping");
6374                mHandler.post(new Runnable() {
6375                @Override
6376                    public void run(){
6377                        try {
6378                            IBackupManager bm = IBackupManager.Stub.asInterface(
6379                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6380                            bm.agentDisconnected(app.info.packageName);
6381                        } catch (RemoteException e) {
6382                            // Can't happen; the backup manager is local
6383                        }
6384                    }
6385                });
6386            }
6387            if (isPendingBroadcastProcessLocked(pid)) {
6388                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6389                skipPendingBroadcastLocked(pid);
6390            }
6391        } else {
6392            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6393        }
6394    }
6395
6396    private final boolean attachApplicationLocked(IApplicationThread thread,
6397            int pid) {
6398
6399        // Find the application record that is being attached...  either via
6400        // the pid if we are running in multiple processes, or just pull the
6401        // next app record if we are emulating process with anonymous threads.
6402        ProcessRecord app;
6403        if (pid != MY_PID && pid >= 0) {
6404            synchronized (mPidsSelfLocked) {
6405                app = mPidsSelfLocked.get(pid);
6406            }
6407        } else {
6408            app = null;
6409        }
6410
6411        if (app == null) {
6412            Slog.w(TAG, "No pending application record for pid " + pid
6413                    + " (IApplicationThread " + thread + "); dropping process");
6414            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6415            if (pid > 0 && pid != MY_PID) {
6416                Process.killProcessQuiet(pid);
6417                //TODO: killProcessGroup(app.info.uid, pid);
6418            } else {
6419                try {
6420                    thread.scheduleExit();
6421                } catch (Exception e) {
6422                    // Ignore exceptions.
6423                }
6424            }
6425            return false;
6426        }
6427
6428        // If this application record is still attached to a previous
6429        // process, clean it up now.
6430        if (app.thread != null) {
6431            handleAppDiedLocked(app, true, true);
6432        }
6433
6434        // Tell the process all about itself.
6435
6436        if (DEBUG_ALL) Slog.v(
6437                TAG, "Binding process pid " + pid + " to record " + app);
6438
6439        final String processName = app.processName;
6440        try {
6441            AppDeathRecipient adr = new AppDeathRecipient(
6442                    app, pid, thread);
6443            thread.asBinder().linkToDeath(adr, 0);
6444            app.deathRecipient = adr;
6445        } catch (RemoteException e) {
6446            app.resetPackageList(mProcessStats);
6447            startProcessLocked(app, "link fail", processName);
6448            return false;
6449        }
6450
6451        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6452
6453        app.makeActive(thread, mProcessStats);
6454        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6455        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6456        app.forcingToForeground = null;
6457        updateProcessForegroundLocked(app, false, false);
6458        app.hasShownUi = false;
6459        app.debugging = false;
6460        app.cached = false;
6461        app.killedByAm = false;
6462        app.killed = false;
6463
6464
6465        // We carefully use the same state that PackageManager uses for
6466        // filtering, since we use this flag to decide if we need to install
6467        // providers when user is unlocked later
6468        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6469
6470        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6471
6472        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6473        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6474
6475        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6476            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6477            msg.obj = app;
6478            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6479        }
6480
6481        if (!normalMode) {
6482            Slog.i(TAG, "Launching preboot mode app: " + app);
6483        }
6484
6485        if (DEBUG_ALL) Slog.v(
6486            TAG, "New app record " + app
6487            + " thread=" + thread.asBinder() + " pid=" + pid);
6488        try {
6489            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6490            if (mDebugApp != null && mDebugApp.equals(processName)) {
6491                testMode = mWaitForDebugger
6492                    ? ApplicationThreadConstants.DEBUG_WAIT
6493                    : ApplicationThreadConstants.DEBUG_ON;
6494                app.debugging = true;
6495                if (mDebugTransient) {
6496                    mDebugApp = mOrigDebugApp;
6497                    mWaitForDebugger = mOrigWaitForDebugger;
6498                }
6499            }
6500            String profileFile = app.instrumentationProfileFile;
6501            ParcelFileDescriptor profileFd = null;
6502            int samplingInterval = 0;
6503            boolean profileAutoStop = false;
6504            if (mProfileApp != null && mProfileApp.equals(processName)) {
6505                mProfileProc = app;
6506                profileFile = mProfileFile;
6507                profileFd = mProfileFd;
6508                samplingInterval = mSamplingInterval;
6509                profileAutoStop = mAutoStopProfiler;
6510            }
6511            boolean enableTrackAllocation = false;
6512            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6513                enableTrackAllocation = true;
6514                mTrackAllocationApp = null;
6515            }
6516
6517            // If the app is being launched for restore or full backup, set it up specially
6518            boolean isRestrictedBackupMode = false;
6519            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6520                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6521                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6522                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6523                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6524            }
6525
6526            if (app.instrumentationClass != null) {
6527                notifyPackageUse(app.instrumentationClass.getPackageName(),
6528                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6529            }
6530            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6531                    + processName + " with config " + getGlobalConfiguration());
6532            ApplicationInfo appInfo = app.instrumentationInfo != null
6533                    ? app.instrumentationInfo : app.info;
6534            app.compat = compatibilityInfoForPackageLocked(appInfo);
6535            if (profileFd != null) {
6536                profileFd = profileFd.dup();
6537            }
6538            ProfilerInfo profilerInfo = profileFile == null ? null
6539                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6540
6541            // We deprecated Build.SERIAL and only apps that target pre NMR1
6542            // SDK can see it. Since access to the serial is now behind a
6543            // permission we push down the value.
6544            String buildSerial = Build.UNKNOWN;
6545            // TODO: SHTOPSHIP Uncomment the check when clients migrate
6546//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6547                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6548                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6549                        .getSerial();
6550//            }
6551
6552            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6553                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6554                    app.instrumentationUiAutomationConnection, testMode,
6555                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6556                    isRestrictedBackupMode || !normalMode, app.persistent,
6557                    new Configuration(getGlobalConfiguration()), app.compat,
6558                    getCommonServicesLocked(app.isolated),
6559                    mCoreSettingsObserver.getCoreSettingsLocked(),
6560                    buildSerial);
6561
6562            updateLruProcessLocked(app, false, null);
6563            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6564        } catch (Exception e) {
6565            // todo: Yikes!  What should we do?  For now we will try to
6566            // start another process, but that could easily get us in
6567            // an infinite loop of restarting processes...
6568            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6569
6570            app.resetPackageList(mProcessStats);
6571            app.unlinkDeathRecipient();
6572            startProcessLocked(app, "bind fail", processName);
6573            return false;
6574        }
6575
6576        // Remove this record from the list of starting applications.
6577        mPersistentStartingProcesses.remove(app);
6578        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6579                "Attach application locked removing on hold: " + app);
6580        mProcessesOnHold.remove(app);
6581
6582        boolean badApp = false;
6583        boolean didSomething = false;
6584
6585        // See if the top visible activity is waiting to run in this process...
6586        if (normalMode) {
6587            try {
6588                if (mStackSupervisor.attachApplicationLocked(app)) {
6589                    didSomething = true;
6590                }
6591            } catch (Exception e) {
6592                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6593                badApp = true;
6594            }
6595        }
6596
6597        // Find any services that should be running in this process...
6598        if (!badApp) {
6599            try {
6600                didSomething |= mServices.attachApplicationLocked(app, processName);
6601            } catch (Exception e) {
6602                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6603                badApp = true;
6604            }
6605        }
6606
6607        // Check if a next-broadcast receiver is in this process...
6608        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6609            try {
6610                didSomething |= sendPendingBroadcastsLocked(app);
6611            } catch (Exception e) {
6612                // If the app died trying to launch the receiver we declare it 'bad'
6613                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6614                badApp = true;
6615            }
6616        }
6617
6618        // Check whether the next backup agent is in this process...
6619        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6620            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6621                    "New app is backup target, launching agent for " + app);
6622            notifyPackageUse(mBackupTarget.appInfo.packageName,
6623                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6624            try {
6625                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6626                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6627                        mBackupTarget.backupMode);
6628            } catch (Exception e) {
6629                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6630                badApp = true;
6631            }
6632        }
6633
6634        if (badApp) {
6635            app.kill("error during init", true);
6636            handleAppDiedLocked(app, false, true);
6637            return false;
6638        }
6639
6640        if (!didSomething) {
6641            updateOomAdjLocked();
6642        }
6643
6644        return true;
6645    }
6646
6647    @Override
6648    public final void attachApplication(IApplicationThread thread) {
6649        synchronized (this) {
6650            int callingPid = Binder.getCallingPid();
6651            final long origId = Binder.clearCallingIdentity();
6652            attachApplicationLocked(thread, callingPid);
6653            Binder.restoreCallingIdentity(origId);
6654        }
6655    }
6656
6657    @Override
6658    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6659        final long origId = Binder.clearCallingIdentity();
6660        synchronized (this) {
6661            ActivityStack stack = ActivityRecord.getStackLocked(token);
6662            if (stack != null) {
6663                ActivityRecord r =
6664                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6665                if (stopProfiling) {
6666                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6667                        try {
6668                            mProfileFd.close();
6669                        } catch (IOException e) {
6670                        }
6671                        clearProfilerLocked();
6672                    }
6673                }
6674            }
6675        }
6676        Binder.restoreCallingIdentity(origId);
6677    }
6678
6679    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6680        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6681                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6682    }
6683
6684    void enableScreenAfterBoot() {
6685        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6686                SystemClock.uptimeMillis());
6687        mWindowManager.enableScreenAfterBoot();
6688
6689        synchronized (this) {
6690            updateEventDispatchingLocked();
6691        }
6692    }
6693
6694    @Override
6695    public void showBootMessage(final CharSequence msg, final boolean always) {
6696        if (Binder.getCallingUid() != Process.myUid()) {
6697            throw new SecurityException();
6698        }
6699        mWindowManager.showBootMessage(msg, always);
6700    }
6701
6702    @Override
6703    public void keyguardGoingAway(int flags) {
6704        enforceNotIsolatedCaller("keyguardGoingAway");
6705        final long token = Binder.clearCallingIdentity();
6706        try {
6707            synchronized (this) {
6708                mKeyguardController.keyguardGoingAway(flags);
6709            }
6710        } finally {
6711            Binder.restoreCallingIdentity(token);
6712        }
6713    }
6714
6715    /**
6716     * @return whther the keyguard is currently locked.
6717     */
6718    boolean isKeyguardLocked() {
6719        return mKeyguardController.isKeyguardLocked();
6720    }
6721
6722    final void finishBooting() {
6723        synchronized (this) {
6724            if (!mBootAnimationComplete) {
6725                mCallFinishBooting = true;
6726                return;
6727            }
6728            mCallFinishBooting = false;
6729        }
6730
6731        ArraySet<String> completedIsas = new ArraySet<String>();
6732        for (String abi : Build.SUPPORTED_ABIS) {
6733            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6734            final String instructionSet = VMRuntime.getInstructionSet(abi);
6735            if (!completedIsas.contains(instructionSet)) {
6736                try {
6737                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6738                } catch (InstallerException e) {
6739                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6740                            e.getMessage() +")");
6741                }
6742                completedIsas.add(instructionSet);
6743            }
6744        }
6745
6746        IntentFilter pkgFilter = new IntentFilter();
6747        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6748        pkgFilter.addDataScheme("package");
6749        mContext.registerReceiver(new BroadcastReceiver() {
6750            @Override
6751            public void onReceive(Context context, Intent intent) {
6752                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6753                if (pkgs != null) {
6754                    for (String pkg : pkgs) {
6755                        synchronized (ActivityManagerService.this) {
6756                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6757                                    0, "query restart")) {
6758                                setResultCode(Activity.RESULT_OK);
6759                                return;
6760                            }
6761                        }
6762                    }
6763                }
6764            }
6765        }, pkgFilter);
6766
6767        IntentFilter dumpheapFilter = new IntentFilter();
6768        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6769        mContext.registerReceiver(new BroadcastReceiver() {
6770            @Override
6771            public void onReceive(Context context, Intent intent) {
6772                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6773                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6774                } else {
6775                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6776                }
6777            }
6778        }, dumpheapFilter);
6779
6780        // Let system services know.
6781        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6782
6783        synchronized (this) {
6784            // Ensure that any processes we had put on hold are now started
6785            // up.
6786            final int NP = mProcessesOnHold.size();
6787            if (NP > 0) {
6788                ArrayList<ProcessRecord> procs =
6789                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6790                for (int ip=0; ip<NP; ip++) {
6791                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6792                            + procs.get(ip));
6793                    startProcessLocked(procs.get(ip), "on-hold", null);
6794                }
6795            }
6796
6797            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6798                // Start looking for apps that are abusing wake locks.
6799                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6800                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6801                // Tell anyone interested that we are done booting!
6802                SystemProperties.set("sys.boot_completed", "1");
6803
6804                // And trigger dev.bootcomplete if we are not showing encryption progress
6805                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6806                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6807                    SystemProperties.set("dev.bootcomplete", "1");
6808                }
6809                mUserController.sendBootCompletedLocked(
6810                        new IIntentReceiver.Stub() {
6811                            @Override
6812                            public void performReceive(Intent intent, int resultCode,
6813                                    String data, Bundle extras, boolean ordered,
6814                                    boolean sticky, int sendingUser) {
6815                                synchronized (ActivityManagerService.this) {
6816                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6817                                            true, false);
6818                                }
6819                            }
6820                        });
6821                scheduleStartProfilesLocked();
6822            }
6823        }
6824    }
6825
6826    @Override
6827    public void bootAnimationComplete() {
6828        final boolean callFinishBooting;
6829        synchronized (this) {
6830            callFinishBooting = mCallFinishBooting;
6831            mBootAnimationComplete = true;
6832        }
6833        if (callFinishBooting) {
6834            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6835            finishBooting();
6836            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6837        }
6838    }
6839
6840    final void ensureBootCompleted() {
6841        boolean booting;
6842        boolean enableScreen;
6843        synchronized (this) {
6844            booting = mBooting;
6845            mBooting = false;
6846            enableScreen = !mBooted;
6847            mBooted = true;
6848        }
6849
6850        if (booting) {
6851            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6852            finishBooting();
6853            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6854        }
6855
6856        if (enableScreen) {
6857            enableScreenAfterBoot();
6858        }
6859    }
6860
6861    @Override
6862    public final void activityResumed(IBinder token) {
6863        final long origId = Binder.clearCallingIdentity();
6864        synchronized(this) {
6865            ActivityRecord.activityResumedLocked(token);
6866            mWindowManager.notifyAppResumedFinished(token);
6867        }
6868        Binder.restoreCallingIdentity(origId);
6869    }
6870
6871    @Override
6872    public final void activityPaused(IBinder token) {
6873        final long origId = Binder.clearCallingIdentity();
6874        synchronized(this) {
6875            ActivityStack stack = ActivityRecord.getStackLocked(token);
6876            if (stack != null) {
6877                stack.activityPausedLocked(token, false);
6878            }
6879        }
6880        Binder.restoreCallingIdentity(origId);
6881    }
6882
6883    @Override
6884    public final void activityStopped(IBinder token, Bundle icicle,
6885            PersistableBundle persistentState, CharSequence description) {
6886        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6887
6888        // Refuse possible leaked file descriptors
6889        if (icicle != null && icicle.hasFileDescriptors()) {
6890            throw new IllegalArgumentException("File descriptors passed in Bundle");
6891        }
6892
6893        final long origId = Binder.clearCallingIdentity();
6894
6895        synchronized (this) {
6896            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6897            if (r != null) {
6898                r.activityStoppedLocked(icicle, persistentState, description);
6899            }
6900        }
6901
6902        trimApplications();
6903
6904        Binder.restoreCallingIdentity(origId);
6905    }
6906
6907    @Override
6908    public final void activityDestroyed(IBinder token) {
6909        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6910        synchronized (this) {
6911            ActivityStack stack = ActivityRecord.getStackLocked(token);
6912            if (stack != null) {
6913                stack.activityDestroyedLocked(token, "activityDestroyed");
6914            }
6915        }
6916    }
6917
6918    @Override
6919    public final void activityRelaunched(IBinder token) {
6920        final long origId = Binder.clearCallingIdentity();
6921        synchronized (this) {
6922            mStackSupervisor.activityRelaunchedLocked(token);
6923        }
6924        Binder.restoreCallingIdentity(origId);
6925    }
6926
6927    @Override
6928    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6929            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6930        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6931                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6932        synchronized (this) {
6933            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6934            if (record == null) {
6935                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6936                        + "found for: " + token);
6937            }
6938            record.setSizeConfigurations(horizontalSizeConfiguration,
6939                    verticalSizeConfigurations, smallestSizeConfigurations);
6940        }
6941    }
6942
6943    @Override
6944    public final void backgroundResourcesReleased(IBinder token) {
6945        final long origId = Binder.clearCallingIdentity();
6946        try {
6947            synchronized (this) {
6948                ActivityStack stack = ActivityRecord.getStackLocked(token);
6949                if (stack != null) {
6950                    stack.backgroundResourcesReleased();
6951                }
6952            }
6953        } finally {
6954            Binder.restoreCallingIdentity(origId);
6955        }
6956    }
6957
6958    @Override
6959    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6960        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6961    }
6962
6963    @Override
6964    public final void notifyEnterAnimationComplete(IBinder token) {
6965        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6966    }
6967
6968    @Override
6969    public String getCallingPackage(IBinder token) {
6970        synchronized (this) {
6971            ActivityRecord r = getCallingRecordLocked(token);
6972            return r != null ? r.info.packageName : null;
6973        }
6974    }
6975
6976    @Override
6977    public ComponentName getCallingActivity(IBinder token) {
6978        synchronized (this) {
6979            ActivityRecord r = getCallingRecordLocked(token);
6980            return r != null ? r.intent.getComponent() : null;
6981        }
6982    }
6983
6984    private ActivityRecord getCallingRecordLocked(IBinder token) {
6985        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6986        if (r == null) {
6987            return null;
6988        }
6989        return r.resultTo;
6990    }
6991
6992    @Override
6993    public ComponentName getActivityClassForToken(IBinder token) {
6994        synchronized(this) {
6995            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6996            if (r == null) {
6997                return null;
6998            }
6999            return r.intent.getComponent();
7000        }
7001    }
7002
7003    @Override
7004    public String getPackageForToken(IBinder token) {
7005        synchronized(this) {
7006            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7007            if (r == null) {
7008                return null;
7009            }
7010            return r.packageName;
7011        }
7012    }
7013
7014    @Override
7015    public boolean isRootVoiceInteraction(IBinder token) {
7016        synchronized(this) {
7017            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7018            if (r == null) {
7019                return false;
7020            }
7021            return r.rootVoiceInteraction;
7022        }
7023    }
7024
7025    @Override
7026    public IIntentSender getIntentSender(int type,
7027            String packageName, IBinder token, String resultWho,
7028            int requestCode, Intent[] intents, String[] resolvedTypes,
7029            int flags, Bundle bOptions, int userId) {
7030        enforceNotIsolatedCaller("getIntentSender");
7031        // Refuse possible leaked file descriptors
7032        if (intents != null) {
7033            if (intents.length < 1) {
7034                throw new IllegalArgumentException("Intents array length must be >= 1");
7035            }
7036            for (int i=0; i<intents.length; i++) {
7037                Intent intent = intents[i];
7038                if (intent != null) {
7039                    if (intent.hasFileDescriptors()) {
7040                        throw new IllegalArgumentException("File descriptors passed in Intent");
7041                    }
7042                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7043                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7044                        throw new IllegalArgumentException(
7045                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7046                    }
7047                    intents[i] = new Intent(intent);
7048                }
7049            }
7050            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7051                throw new IllegalArgumentException(
7052                        "Intent array length does not match resolvedTypes length");
7053            }
7054        }
7055        if (bOptions != null) {
7056            if (bOptions.hasFileDescriptors()) {
7057                throw new IllegalArgumentException("File descriptors passed in options");
7058            }
7059        }
7060
7061        synchronized(this) {
7062            int callingUid = Binder.getCallingUid();
7063            int origUserId = userId;
7064            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7065                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7066                    ALLOW_NON_FULL, "getIntentSender", null);
7067            if (origUserId == UserHandle.USER_CURRENT) {
7068                // We don't want to evaluate this until the pending intent is
7069                // actually executed.  However, we do want to always do the
7070                // security checking for it above.
7071                userId = UserHandle.USER_CURRENT;
7072            }
7073            try {
7074                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7075                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7076                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7077                    if (!UserHandle.isSameApp(callingUid, uid)) {
7078                        String msg = "Permission Denial: getIntentSender() from pid="
7079                            + Binder.getCallingPid()
7080                            + ", uid=" + Binder.getCallingUid()
7081                            + ", (need uid=" + uid + ")"
7082                            + " is not allowed to send as package " + packageName;
7083                        Slog.w(TAG, msg);
7084                        throw new SecurityException(msg);
7085                    }
7086                }
7087
7088                return getIntentSenderLocked(type, packageName, callingUid, userId,
7089                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7090
7091            } catch (RemoteException e) {
7092                throw new SecurityException(e);
7093            }
7094        }
7095    }
7096
7097    IIntentSender getIntentSenderLocked(int type, String packageName,
7098            int callingUid, int userId, IBinder token, String resultWho,
7099            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7100            Bundle bOptions) {
7101        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7102        ActivityRecord activity = null;
7103        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7104            activity = ActivityRecord.isInStackLocked(token);
7105            if (activity == null) {
7106                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7107                return null;
7108            }
7109            if (activity.finishing) {
7110                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7111                return null;
7112            }
7113        }
7114
7115        // We're going to be splicing together extras before sending, so we're
7116        // okay poking into any contained extras.
7117        if (intents != null) {
7118            for (int i = 0; i < intents.length; i++) {
7119                intents[i].setDefusable(true);
7120            }
7121        }
7122        Bundle.setDefusable(bOptions, true);
7123
7124        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7125        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7126        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7127        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7128                |PendingIntent.FLAG_UPDATE_CURRENT);
7129
7130        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7131                type, packageName, activity, resultWho,
7132                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7133        WeakReference<PendingIntentRecord> ref;
7134        ref = mIntentSenderRecords.get(key);
7135        PendingIntentRecord rec = ref != null ? ref.get() : null;
7136        if (rec != null) {
7137            if (!cancelCurrent) {
7138                if (updateCurrent) {
7139                    if (rec.key.requestIntent != null) {
7140                        rec.key.requestIntent.replaceExtras(intents != null ?
7141                                intents[intents.length - 1] : null);
7142                    }
7143                    if (intents != null) {
7144                        intents[intents.length-1] = rec.key.requestIntent;
7145                        rec.key.allIntents = intents;
7146                        rec.key.allResolvedTypes = resolvedTypes;
7147                    } else {
7148                        rec.key.allIntents = null;
7149                        rec.key.allResolvedTypes = null;
7150                    }
7151                }
7152                return rec;
7153            }
7154            rec.canceled = true;
7155            mIntentSenderRecords.remove(key);
7156        }
7157        if (noCreate) {
7158            return rec;
7159        }
7160        rec = new PendingIntentRecord(this, key, callingUid);
7161        mIntentSenderRecords.put(key, rec.ref);
7162        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7163            if (activity.pendingResults == null) {
7164                activity.pendingResults
7165                        = new HashSet<WeakReference<PendingIntentRecord>>();
7166            }
7167            activity.pendingResults.add(rec.ref);
7168        }
7169        return rec;
7170    }
7171
7172    @Override
7173    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7174            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7175        if (target instanceof PendingIntentRecord) {
7176            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7177                    finishedReceiver, requiredPermission, options);
7178        } else {
7179            if (intent == null) {
7180                // Weird case: someone has given us their own custom IIntentSender, and now
7181                // they have someone else trying to send to it but of course this isn't
7182                // really a PendingIntent, so there is no base Intent, and the caller isn't
7183                // supplying an Intent... but we never want to dispatch a null Intent to
7184                // a receiver, so um...  let's make something up.
7185                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7186                intent = new Intent(Intent.ACTION_MAIN);
7187            }
7188            try {
7189                target.send(code, intent, resolvedType, null, requiredPermission, options);
7190            } catch (RemoteException e) {
7191            }
7192            // Platform code can rely on getting a result back when the send is done, but if
7193            // this intent sender is from outside of the system we can't rely on it doing that.
7194            // So instead we don't give it the result receiver, and instead just directly
7195            // report the finish immediately.
7196            if (finishedReceiver != null) {
7197                try {
7198                    finishedReceiver.performReceive(intent, 0,
7199                            null, null, false, false, UserHandle.getCallingUserId());
7200                } catch (RemoteException e) {
7201                }
7202            }
7203            return 0;
7204        }
7205    }
7206
7207    /**
7208     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7209     *
7210     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7211     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7212     */
7213    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7214        if (DEBUG_WHITELISTS) {
7215            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7216                    + targetUid + ", " + duration + ")");
7217        }
7218        synchronized (mPidsSelfLocked) {
7219            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7220            if (pr == null) {
7221                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7222                return;
7223            }
7224            if (!pr.whitelistManager) {
7225                if (DEBUG_WHITELISTS) {
7226                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7227                            + callerPid + " is not allowed");
7228                }
7229                return;
7230            }
7231        }
7232
7233        final long token = Binder.clearCallingIdentity();
7234        try {
7235            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7236                    true, "pe from uid:" + callerUid);
7237        } finally {
7238            Binder.restoreCallingIdentity(token);
7239        }
7240    }
7241
7242    @Override
7243    public void cancelIntentSender(IIntentSender sender) {
7244        if (!(sender instanceof PendingIntentRecord)) {
7245            return;
7246        }
7247        synchronized(this) {
7248            PendingIntentRecord rec = (PendingIntentRecord)sender;
7249            try {
7250                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7251                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7252                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7253                    String msg = "Permission Denial: cancelIntentSender() from pid="
7254                        + Binder.getCallingPid()
7255                        + ", uid=" + Binder.getCallingUid()
7256                        + " is not allowed to cancel packges "
7257                        + rec.key.packageName;
7258                    Slog.w(TAG, msg);
7259                    throw new SecurityException(msg);
7260                }
7261            } catch (RemoteException e) {
7262                throw new SecurityException(e);
7263            }
7264            cancelIntentSenderLocked(rec, true);
7265        }
7266    }
7267
7268    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7269        rec.canceled = true;
7270        mIntentSenderRecords.remove(rec.key);
7271        if (cleanActivity && rec.key.activity != null) {
7272            rec.key.activity.pendingResults.remove(rec.ref);
7273        }
7274    }
7275
7276    @Override
7277    public String getPackageForIntentSender(IIntentSender pendingResult) {
7278        if (!(pendingResult instanceof PendingIntentRecord)) {
7279            return null;
7280        }
7281        try {
7282            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7283            return res.key.packageName;
7284        } catch (ClassCastException e) {
7285        }
7286        return null;
7287    }
7288
7289    @Override
7290    public int getUidForIntentSender(IIntentSender sender) {
7291        if (sender instanceof PendingIntentRecord) {
7292            try {
7293                PendingIntentRecord res = (PendingIntentRecord)sender;
7294                return res.uid;
7295            } catch (ClassCastException e) {
7296            }
7297        }
7298        return -1;
7299    }
7300
7301    @Override
7302    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7303        if (!(pendingResult instanceof PendingIntentRecord)) {
7304            return false;
7305        }
7306        try {
7307            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7308            if (res.key.allIntents == null) {
7309                return false;
7310            }
7311            for (int i=0; i<res.key.allIntents.length; i++) {
7312                Intent intent = res.key.allIntents[i];
7313                if (intent.getPackage() != null && intent.getComponent() != null) {
7314                    return false;
7315                }
7316            }
7317            return true;
7318        } catch (ClassCastException e) {
7319        }
7320        return false;
7321    }
7322
7323    @Override
7324    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7325        if (!(pendingResult instanceof PendingIntentRecord)) {
7326            return false;
7327        }
7328        try {
7329            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7330            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7331                return true;
7332            }
7333            return false;
7334        } catch (ClassCastException e) {
7335        }
7336        return false;
7337    }
7338
7339    @Override
7340    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7341        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7342                "getIntentForIntentSender()");
7343        if (!(pendingResult instanceof PendingIntentRecord)) {
7344            return null;
7345        }
7346        try {
7347            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7348            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7349        } catch (ClassCastException e) {
7350        }
7351        return null;
7352    }
7353
7354    @Override
7355    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7356        if (!(pendingResult instanceof PendingIntentRecord)) {
7357            return null;
7358        }
7359        try {
7360            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7361            synchronized (this) {
7362                return getTagForIntentSenderLocked(res, prefix);
7363            }
7364        } catch (ClassCastException e) {
7365        }
7366        return null;
7367    }
7368
7369    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7370        final Intent intent = res.key.requestIntent;
7371        if (intent != null) {
7372            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7373                    || res.lastTagPrefix.equals(prefix))) {
7374                return res.lastTag;
7375            }
7376            res.lastTagPrefix = prefix;
7377            final StringBuilder sb = new StringBuilder(128);
7378            if (prefix != null) {
7379                sb.append(prefix);
7380            }
7381            if (intent.getAction() != null) {
7382                sb.append(intent.getAction());
7383            } else if (intent.getComponent() != null) {
7384                intent.getComponent().appendShortString(sb);
7385            } else {
7386                sb.append("?");
7387            }
7388            return res.lastTag = sb.toString();
7389        }
7390        return null;
7391    }
7392
7393    @Override
7394    public void setProcessLimit(int max) {
7395        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7396                "setProcessLimit()");
7397        synchronized (this) {
7398            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7399            mProcessLimitOverride = max;
7400        }
7401        trimApplications();
7402    }
7403
7404    @Override
7405    public int getProcessLimit() {
7406        synchronized (this) {
7407            return mProcessLimitOverride;
7408        }
7409    }
7410
7411    void foregroundTokenDied(ForegroundToken token) {
7412        synchronized (ActivityManagerService.this) {
7413            synchronized (mPidsSelfLocked) {
7414                ForegroundToken cur
7415                    = mForegroundProcesses.get(token.pid);
7416                if (cur != token) {
7417                    return;
7418                }
7419                mForegroundProcesses.remove(token.pid);
7420                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7421                if (pr == null) {
7422                    return;
7423                }
7424                pr.forcingToForeground = null;
7425                updateProcessForegroundLocked(pr, false, false);
7426            }
7427            updateOomAdjLocked();
7428        }
7429    }
7430
7431    @Override
7432    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7433        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7434                "setProcessForeground()");
7435        synchronized(this) {
7436            boolean changed = false;
7437
7438            synchronized (mPidsSelfLocked) {
7439                ProcessRecord pr = mPidsSelfLocked.get(pid);
7440                if (pr == null && isForeground) {
7441                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7442                    return;
7443                }
7444                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7445                if (oldToken != null) {
7446                    oldToken.token.unlinkToDeath(oldToken, 0);
7447                    mForegroundProcesses.remove(pid);
7448                    if (pr != null) {
7449                        pr.forcingToForeground = null;
7450                    }
7451                    changed = true;
7452                }
7453                if (isForeground && token != null) {
7454                    ForegroundToken newToken = new ForegroundToken() {
7455                        @Override
7456                        public void binderDied() {
7457                            foregroundTokenDied(this);
7458                        }
7459                    };
7460                    newToken.pid = pid;
7461                    newToken.token = token;
7462                    try {
7463                        token.linkToDeath(newToken, 0);
7464                        mForegroundProcesses.put(pid, newToken);
7465                        pr.forcingToForeground = token;
7466                        changed = true;
7467                    } catch (RemoteException e) {
7468                        // If the process died while doing this, we will later
7469                        // do the cleanup with the process death link.
7470                    }
7471                }
7472            }
7473
7474            if (changed) {
7475                updateOomAdjLocked();
7476            }
7477        }
7478    }
7479
7480    @Override
7481    public boolean isAppForeground(int uid) throws RemoteException {
7482        synchronized (this) {
7483            UidRecord uidRec = mActiveUids.get(uid);
7484            if (uidRec == null || uidRec.idle) {
7485                return false;
7486            }
7487            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7488        }
7489    }
7490
7491    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7492    // be guarded by permission checking.
7493    int getUidState(int uid) {
7494        synchronized (this) {
7495            UidRecord uidRec = mActiveUids.get(uid);
7496            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7497        }
7498    }
7499
7500    @Override
7501    public boolean isInMultiWindowMode(IBinder token) {
7502        final long origId = Binder.clearCallingIdentity();
7503        try {
7504            synchronized(this) {
7505                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7506                if (r == null) {
7507                    return false;
7508                }
7509                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7510                return !r.task.mFullscreen;
7511            }
7512        } finally {
7513            Binder.restoreCallingIdentity(origId);
7514        }
7515    }
7516
7517    @Override
7518    public boolean isInPictureInPictureMode(IBinder token) {
7519        final long origId = Binder.clearCallingIdentity();
7520        try {
7521            synchronized(this) {
7522                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7523                if (stack == null) {
7524                    return false;
7525                }
7526                return stack.mStackId == PINNED_STACK_ID;
7527            }
7528        } finally {
7529            Binder.restoreCallingIdentity(origId);
7530        }
7531    }
7532
7533    @Override
7534    public void enterPictureInPictureMode(IBinder token) {
7535        enterPictureInPictureMode(token, DEFAULT_DISPLAY, -1f /* aspectRatio */,
7536                false /* checkAspectRatio */);
7537    }
7538
7539    @Override
7540    public void enterPictureInPictureModeWithAspectRatio(IBinder token, float aspectRatio) {
7541        enterPictureInPictureMode(token, DEFAULT_DISPLAY, aspectRatio, true /* checkAspectRatio */);
7542    }
7543
7544    @Override
7545    public void enterPictureInPictureModeOnMoveToBackground(IBinder token,
7546            boolean enterPictureInPictureOnMoveToBg) {
7547        final long origId = Binder.clearCallingIdentity();
7548        try {
7549            synchronized(this) {
7550                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7551                        "enterPictureInPictureModeOnMoveToBackground", token, -1f /* aspectRatio */,
7552                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7553
7554                r.supportsPipOnMoveToBackground = enterPictureInPictureOnMoveToBg;
7555            }
7556        } finally {
7557            Binder.restoreCallingIdentity(origId);
7558        }
7559    }
7560
7561    private void enterPictureInPictureMode(IBinder token, int displayId, float aspectRatio,
7562            boolean checkAspectRatio) {
7563        final long origId = Binder.clearCallingIdentity();
7564        try {
7565            synchronized(this) {
7566                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7567                        "enterPictureInPictureMode", token, aspectRatio, checkAspectRatio,
7568                        true /* checkActivityVisibility */);
7569                final Runnable enterPipRunnable = () -> {
7570                    r.pictureInPictureArgs.aspectRatio = aspectRatio;
7571                    enterPictureInPictureModeLocked(r, displayId, r.pictureInPictureArgs,
7572                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7573                };
7574
7575                if (isKeyguardLocked()) {
7576                    // If the keyguard is showing or occluded, then try and dismiss it before
7577                    // entering picture-in-picture (this will prompt the user to authenticate if the
7578                    // device is currently locked).
7579                    try {
7580                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7581                            @Override
7582                            public void onDismissError() throws RemoteException {
7583                                // Do nothing
7584                            }
7585
7586                            @Override
7587                            public void onDismissSucceeded() throws RemoteException {
7588                                mHandler.post(enterPipRunnable);
7589                            }
7590
7591                            @Override
7592                            public void onDismissCancelled() throws RemoteException {
7593                                // Do nothing
7594                            }
7595                        });
7596                    } catch (RemoteException e) {
7597                        // Local call
7598                    }
7599                } else {
7600                    // Enter picture in picture immediately otherwise
7601                    enterPipRunnable.run();
7602                }
7603            }
7604        } finally {
7605            Binder.restoreCallingIdentity(origId);
7606        }
7607    }
7608
7609    void enterPictureInPictureModeLocked(ActivityRecord r, int displayId,
7610            PictureInPictureArguments pipArgs, boolean moveHomeStackToFront, String reason) {
7611        final Rect bounds = isValidPictureInPictureAspectRatio(pipArgs.aspectRatio)
7612                ? mWindowManager.getPictureInPictureBounds(displayId, pipArgs.aspectRatio)
7613                : mWindowManager.getPictureInPictureDefaultBounds(displayId);
7614        mStackSupervisor.moveActivityToPinnedStackLocked(r, reason, bounds, moveHomeStackToFront);
7615        mWindowManager.setPictureInPictureActions(pipArgs.userActions);
7616    }
7617
7618    @Override
7619    public void setPictureInPictureAspectRatio(IBinder token, float aspectRatio) {
7620        final long origId = Binder.clearCallingIdentity();
7621        try {
7622            synchronized(this) {
7623                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7624                        "setPictureInPictureAspectRatio", token, aspectRatio,
7625                        true /* checkAspectRatio */, false /* checkActivityVisibility */);
7626
7627                r.pictureInPictureArgs.aspectRatio = aspectRatio;
7628                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7629                    // If the activity is already in picture-in-picture, update the pinned stack now
7630                    mWindowManager.setPictureInPictureAspectRatio(aspectRatio);
7631                }
7632            }
7633        } finally {
7634            Binder.restoreCallingIdentity(origId);
7635        }
7636    }
7637
7638    @Override
7639    public void setPictureInPictureActions(IBinder token, ParceledListSlice actionsList) {
7640        final long origId = Binder.clearCallingIdentity();
7641        try {
7642            synchronized(this) {
7643                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7644                        "setPictureInPictureActions", token, -1 /* aspectRatio */,
7645                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7646
7647                final List<RemoteAction> actions = actionsList.getList();
7648                if (actions.size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7649                    throw new IllegalArgumentException("setPictureInPictureActions: Invalid number"
7650                            + " of picture-in-picture actions.  Only a maximum of "
7651                            + ActivityManager.getMaxNumPictureInPictureActions()
7652                            + " actions allowed");
7653                }
7654
7655                r.pictureInPictureArgs.userActions = actions;
7656                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7657                    // If the activity is already in picture-in-picture, update the pinned stack now
7658                    mWindowManager.setPictureInPictureActions(actions);
7659                }
7660            }
7661        } finally {
7662            Binder.restoreCallingIdentity(origId);
7663        }
7664    }
7665
7666    private boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
7667        return mMinPipAspectRatio <= aspectRatio && aspectRatio <= mMaxPipAspectRatio;
7668    }
7669
7670    /**
7671     * Checks the state of the system and the activity associated with the given {@param token} to
7672     * verify that picture-in-picture is supported for that activity.
7673     *
7674     * @param checkAspectRatio whether or not to check {@param aspectRatio} is within a valid range
7675     * @param checkActivityVisibility whether or not to enforce that the activity is currently
7676     *                                visible
7677     *
7678     * @return the activity record for the given {@param token} if all the checks pass.
7679     */
7680    private ActivityRecord ensureValidPictureInPictureActivityLocked(String caller, IBinder token,
7681            float aspectRatio, boolean checkAspectRatio, boolean checkActivityVisibility) {
7682        if (!mSupportsPictureInPicture) {
7683            throw new IllegalStateException(caller
7684                    + ": Device doesn't support picture-in-picture mode.");
7685        }
7686
7687        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7688        if (r == null) {
7689            throw new IllegalStateException(caller
7690                    + ": Can't find activity for token=" + token);
7691        }
7692
7693        if (!r.canEnterPictureInPicture(checkActivityVisibility)) {
7694            throw new IllegalArgumentException(caller
7695                    + ": Current activity does not support picture-in-picture or is not "
7696                    + "visible r=" + r);
7697        }
7698
7699        if (r.getStack().isHomeStack()) {
7700            throw new IllegalStateException(caller
7701                    + ": Activities on the home stack not supported");
7702        }
7703
7704        if (checkAspectRatio && !isValidPictureInPictureAspectRatio(aspectRatio)) {
7705            throw new IllegalArgumentException(String.format(caller
7706                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7707                            mMinPipAspectRatio, mMaxPipAspectRatio));
7708        }
7709
7710        return r;
7711    }
7712
7713    // =========================================================
7714    // PROCESS INFO
7715    // =========================================================
7716
7717    static class ProcessInfoService extends IProcessInfoService.Stub {
7718        final ActivityManagerService mActivityManagerService;
7719        ProcessInfoService(ActivityManagerService activityManagerService) {
7720            mActivityManagerService = activityManagerService;
7721        }
7722
7723        @Override
7724        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7725            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7726                    /*in*/ pids, /*out*/ states, null);
7727        }
7728
7729        @Override
7730        public void getProcessStatesAndOomScoresFromPids(
7731                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7732            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7733                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7734        }
7735    }
7736
7737    /**
7738     * For each PID in the given input array, write the current process state
7739     * for that process into the states array, or -1 to indicate that no
7740     * process with the given PID exists. If scores array is provided, write
7741     * the oom score for the process into the scores array, with INVALID_ADJ
7742     * indicating the PID doesn't exist.
7743     */
7744    public void getProcessStatesAndOomScoresForPIDs(
7745            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7746        if (scores != null) {
7747            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7748                    "getProcessStatesAndOomScoresForPIDs()");
7749        }
7750
7751        if (pids == null) {
7752            throw new NullPointerException("pids");
7753        } else if (states == null) {
7754            throw new NullPointerException("states");
7755        } else if (pids.length != states.length) {
7756            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7757        } else if (scores != null && pids.length != scores.length) {
7758            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7759        }
7760
7761        synchronized (mPidsSelfLocked) {
7762            for (int i = 0; i < pids.length; i++) {
7763                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7764                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7765                        pr.curProcState;
7766                if (scores != null) {
7767                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7768                }
7769            }
7770        }
7771    }
7772
7773    // =========================================================
7774    // PERMISSIONS
7775    // =========================================================
7776
7777    static class PermissionController extends IPermissionController.Stub {
7778        ActivityManagerService mActivityManagerService;
7779        PermissionController(ActivityManagerService activityManagerService) {
7780            mActivityManagerService = activityManagerService;
7781        }
7782
7783        @Override
7784        public boolean checkPermission(String permission, int pid, int uid) {
7785            return mActivityManagerService.checkPermission(permission, pid,
7786                    uid) == PackageManager.PERMISSION_GRANTED;
7787        }
7788
7789        @Override
7790        public String[] getPackagesForUid(int uid) {
7791            return mActivityManagerService.mContext.getPackageManager()
7792                    .getPackagesForUid(uid);
7793        }
7794
7795        @Override
7796        public boolean isRuntimePermission(String permission) {
7797            try {
7798                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7799                        .getPermissionInfo(permission, 0);
7800                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7801                        == PermissionInfo.PROTECTION_DANGEROUS;
7802            } catch (NameNotFoundException nnfe) {
7803                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7804            }
7805            return false;
7806        }
7807    }
7808
7809    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7810        @Override
7811        public int checkComponentPermission(String permission, int pid, int uid,
7812                int owningUid, boolean exported) {
7813            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7814                    owningUid, exported);
7815        }
7816
7817        @Override
7818        public Object getAMSLock() {
7819            return ActivityManagerService.this;
7820        }
7821    }
7822
7823    /**
7824     * This can be called with or without the global lock held.
7825     */
7826    int checkComponentPermission(String permission, int pid, int uid,
7827            int owningUid, boolean exported) {
7828        if (pid == MY_PID) {
7829            return PackageManager.PERMISSION_GRANTED;
7830        }
7831        return ActivityManager.checkComponentPermission(permission, uid,
7832                owningUid, exported);
7833    }
7834
7835    /**
7836     * As the only public entry point for permissions checking, this method
7837     * can enforce the semantic that requesting a check on a null global
7838     * permission is automatically denied.  (Internally a null permission
7839     * string is used when calling {@link #checkComponentPermission} in cases
7840     * when only uid-based security is needed.)
7841     *
7842     * This can be called with or without the global lock held.
7843     */
7844    @Override
7845    public int checkPermission(String permission, int pid, int uid) {
7846        if (permission == null) {
7847            return PackageManager.PERMISSION_DENIED;
7848        }
7849        return checkComponentPermission(permission, pid, uid, -1, true);
7850    }
7851
7852    @Override
7853    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7854        if (permission == null) {
7855            return PackageManager.PERMISSION_DENIED;
7856        }
7857
7858        // We might be performing an operation on behalf of an indirect binder
7859        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7860        // client identity accordingly before proceeding.
7861        Identity tlsIdentity = sCallerIdentity.get();
7862        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7863            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7864                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7865            uid = tlsIdentity.uid;
7866            pid = tlsIdentity.pid;
7867        }
7868
7869        return checkComponentPermission(permission, pid, uid, -1, true);
7870    }
7871
7872    /**
7873     * Binder IPC calls go through the public entry point.
7874     * This can be called with or without the global lock held.
7875     */
7876    int checkCallingPermission(String permission) {
7877        return checkPermission(permission,
7878                Binder.getCallingPid(),
7879                UserHandle.getAppId(Binder.getCallingUid()));
7880    }
7881
7882    /**
7883     * This can be called with or without the global lock held.
7884     */
7885    void enforceCallingPermission(String permission, String func) {
7886        if (checkCallingPermission(permission)
7887                == PackageManager.PERMISSION_GRANTED) {
7888            return;
7889        }
7890
7891        String msg = "Permission Denial: " + func + " from pid="
7892                + Binder.getCallingPid()
7893                + ", uid=" + Binder.getCallingUid()
7894                + " requires " + permission;
7895        Slog.w(TAG, msg);
7896        throw new SecurityException(msg);
7897    }
7898
7899    /**
7900     * Determine if UID is holding permissions required to access {@link Uri} in
7901     * the given {@link ProviderInfo}. Final permission checking is always done
7902     * in {@link ContentProvider}.
7903     */
7904    private final boolean checkHoldingPermissionsLocked(
7905            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7906        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7907                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7908        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7909            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7910                    != PERMISSION_GRANTED) {
7911                return false;
7912            }
7913        }
7914        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7915    }
7916
7917    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7918            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7919        if (pi.applicationInfo.uid == uid) {
7920            return true;
7921        } else if (!pi.exported) {
7922            return false;
7923        }
7924
7925        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7926        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7927        try {
7928            // check if target holds top-level <provider> permissions
7929            if (!readMet && pi.readPermission != null && considerUidPermissions
7930                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7931                readMet = true;
7932            }
7933            if (!writeMet && pi.writePermission != null && considerUidPermissions
7934                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7935                writeMet = true;
7936            }
7937
7938            // track if unprotected read/write is allowed; any denied
7939            // <path-permission> below removes this ability
7940            boolean allowDefaultRead = pi.readPermission == null;
7941            boolean allowDefaultWrite = pi.writePermission == null;
7942
7943            // check if target holds any <path-permission> that match uri
7944            final PathPermission[] pps = pi.pathPermissions;
7945            if (pps != null) {
7946                final String path = grantUri.uri.getPath();
7947                int i = pps.length;
7948                while (i > 0 && (!readMet || !writeMet)) {
7949                    i--;
7950                    PathPermission pp = pps[i];
7951                    if (pp.match(path)) {
7952                        if (!readMet) {
7953                            final String pprperm = pp.getReadPermission();
7954                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7955                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7956                                    + ": match=" + pp.match(path)
7957                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7958                            if (pprperm != null) {
7959                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7960                                        == PERMISSION_GRANTED) {
7961                                    readMet = true;
7962                                } else {
7963                                    allowDefaultRead = false;
7964                                }
7965                            }
7966                        }
7967                        if (!writeMet) {
7968                            final String ppwperm = pp.getWritePermission();
7969                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7970                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7971                                    + ": match=" + pp.match(path)
7972                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7973                            if (ppwperm != null) {
7974                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7975                                        == PERMISSION_GRANTED) {
7976                                    writeMet = true;
7977                                } else {
7978                                    allowDefaultWrite = false;
7979                                }
7980                            }
7981                        }
7982                    }
7983                }
7984            }
7985
7986            // grant unprotected <provider> read/write, if not blocked by
7987            // <path-permission> above
7988            if (allowDefaultRead) readMet = true;
7989            if (allowDefaultWrite) writeMet = true;
7990
7991        } catch (RemoteException e) {
7992            return false;
7993        }
7994
7995        return readMet && writeMet;
7996    }
7997
7998    public int getAppStartMode(int uid, String packageName) {
7999        synchronized (this) {
8000            return checkAllowBackgroundLocked(uid, packageName, -1, false);
8001        }
8002    }
8003
8004    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
8005            boolean alwaysRestrict) {
8006        UidRecord uidRec = mActiveUids.get(uid);
8007        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8008            boolean ephemeral;
8009            if (uidRec == null) {
8010                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8011                        UserHandle.getUserId(uid), packageName);
8012            } else {
8013                ephemeral = uidRec.ephemeral;
8014            }
8015
8016            if (ephemeral) {
8017                // We are hard-core about ephemeral apps not running in the background.
8018                return ActivityManager.APP_START_MODE_DISABLED;
8019            } else {
8020                if (callingPid >= 0) {
8021                    ProcessRecord proc;
8022                    synchronized (mPidsSelfLocked) {
8023                        proc = mPidsSelfLocked.get(callingPid);
8024                    }
8025                    if (proc != null && proc.curProcState
8026                            < ActivityManager.PROCESS_STATE_RECEIVER) {
8027                        // Whoever is instigating this is in the foreground, so we will allow it
8028                        // to go through.
8029                        return ActivityManager.APP_START_MODE_NORMAL;
8030                    }
8031                }
8032                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
8033                        packageName) != AppOpsManager.MODE_ALLOWED) {
8034                    return ActivityManager.APP_START_MODE_DELAYED;
8035                }
8036            }
8037        }
8038        return ActivityManager.APP_START_MODE_NORMAL;
8039    }
8040
8041    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8042        ProviderInfo pi = null;
8043        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8044        if (cpr != null) {
8045            pi = cpr.info;
8046        } else {
8047            try {
8048                pi = AppGlobals.getPackageManager().resolveContentProvider(
8049                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8050                        userHandle);
8051            } catch (RemoteException ex) {
8052            }
8053        }
8054        return pi;
8055    }
8056
8057    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8058        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8059        if (targetUris != null) {
8060            return targetUris.get(grantUri);
8061        }
8062        return null;
8063    }
8064
8065    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8066            String targetPkg, int targetUid, GrantUri grantUri) {
8067        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8068        if (targetUris == null) {
8069            targetUris = Maps.newArrayMap();
8070            mGrantedUriPermissions.put(targetUid, targetUris);
8071        }
8072
8073        UriPermission perm = targetUris.get(grantUri);
8074        if (perm == null) {
8075            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8076            targetUris.put(grantUri, perm);
8077        }
8078
8079        return perm;
8080    }
8081
8082    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8083            final int modeFlags) {
8084        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8085        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8086                : UriPermission.STRENGTH_OWNED;
8087
8088        // Root gets to do everything.
8089        if (uid == 0) {
8090            return true;
8091        }
8092
8093        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8094        if (perms == null) return false;
8095
8096        // First look for exact match
8097        final UriPermission exactPerm = perms.get(grantUri);
8098        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8099            return true;
8100        }
8101
8102        // No exact match, look for prefixes
8103        final int N = perms.size();
8104        for (int i = 0; i < N; i++) {
8105            final UriPermission perm = perms.valueAt(i);
8106            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8107                    && perm.getStrength(modeFlags) >= minStrength) {
8108                return true;
8109            }
8110        }
8111
8112        return false;
8113    }
8114
8115    /**
8116     * @param uri This uri must NOT contain an embedded userId.
8117     * @param userId The userId in which the uri is to be resolved.
8118     */
8119    @Override
8120    public int checkUriPermission(Uri uri, int pid, int uid,
8121            final int modeFlags, int userId, IBinder callerToken) {
8122        enforceNotIsolatedCaller("checkUriPermission");
8123
8124        // Another redirected-binder-call permissions check as in
8125        // {@link checkPermissionWithToken}.
8126        Identity tlsIdentity = sCallerIdentity.get();
8127        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8128            uid = tlsIdentity.uid;
8129            pid = tlsIdentity.pid;
8130        }
8131
8132        // Our own process gets to do everything.
8133        if (pid == MY_PID) {
8134            return PackageManager.PERMISSION_GRANTED;
8135        }
8136        synchronized (this) {
8137            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8138                    ? PackageManager.PERMISSION_GRANTED
8139                    : PackageManager.PERMISSION_DENIED;
8140        }
8141    }
8142
8143    /**
8144     * Check if the targetPkg can be granted permission to access uri by
8145     * the callingUid using the given modeFlags.  Throws a security exception
8146     * if callingUid is not allowed to do this.  Returns the uid of the target
8147     * if the URI permission grant should be performed; returns -1 if it is not
8148     * needed (for example targetPkg already has permission to access the URI).
8149     * If you already know the uid of the target, you can supply it in
8150     * lastTargetUid else set that to -1.
8151     */
8152    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8153            final int modeFlags, int lastTargetUid) {
8154        if (!Intent.isAccessUriMode(modeFlags)) {
8155            return -1;
8156        }
8157
8158        if (targetPkg != null) {
8159            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8160                    "Checking grant " + targetPkg + " permission to " + grantUri);
8161        }
8162
8163        final IPackageManager pm = AppGlobals.getPackageManager();
8164
8165        // If this is not a content: uri, we can't do anything with it.
8166        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8167            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8168                    "Can't grant URI permission for non-content URI: " + grantUri);
8169            return -1;
8170        }
8171
8172        final String authority = grantUri.uri.getAuthority();
8173        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8174                MATCH_DEBUG_TRIAGED_MISSING);
8175        if (pi == null) {
8176            Slog.w(TAG, "No content provider found for permission check: " +
8177                    grantUri.uri.toSafeString());
8178            return -1;
8179        }
8180
8181        int targetUid = lastTargetUid;
8182        if (targetUid < 0 && targetPkg != null) {
8183            try {
8184                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8185                        UserHandle.getUserId(callingUid));
8186                if (targetUid < 0) {
8187                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8188                            "Can't grant URI permission no uid for: " + targetPkg);
8189                    return -1;
8190                }
8191            } catch (RemoteException ex) {
8192                return -1;
8193            }
8194        }
8195
8196        // If we're extending a persistable grant, then we always need to create
8197        // the grant data structure so that take/release APIs work
8198        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8199            return targetUid;
8200        }
8201
8202        if (targetUid >= 0) {
8203            // First...  does the target actually need this permission?
8204            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8205                // No need to grant the target this permission.
8206                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8207                        "Target " + targetPkg + " already has full permission to " + grantUri);
8208                return -1;
8209            }
8210        } else {
8211            // First...  there is no target package, so can anyone access it?
8212            boolean allowed = pi.exported;
8213            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8214                if (pi.readPermission != null) {
8215                    allowed = false;
8216                }
8217            }
8218            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8219                if (pi.writePermission != null) {
8220                    allowed = false;
8221                }
8222            }
8223            if (allowed) {
8224                return -1;
8225            }
8226        }
8227
8228        /* There is a special cross user grant if:
8229         * - The target is on another user.
8230         * - Apps on the current user can access the uri without any uid permissions.
8231         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8232         * grant uri permissions.
8233         */
8234        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8235                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8236                modeFlags, false /*without considering the uid permissions*/);
8237
8238        // Second...  is the provider allowing granting of URI permissions?
8239        if (!specialCrossUserGrant) {
8240            if (!pi.grantUriPermissions) {
8241                throw new SecurityException("Provider " + pi.packageName
8242                        + "/" + pi.name
8243                        + " does not allow granting of Uri permissions (uri "
8244                        + grantUri + ")");
8245            }
8246            if (pi.uriPermissionPatterns != null) {
8247                final int N = pi.uriPermissionPatterns.length;
8248                boolean allowed = false;
8249                for (int i=0; i<N; i++) {
8250                    if (pi.uriPermissionPatterns[i] != null
8251                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8252                        allowed = true;
8253                        break;
8254                    }
8255                }
8256                if (!allowed) {
8257                    throw new SecurityException("Provider " + pi.packageName
8258                            + "/" + pi.name
8259                            + " does not allow granting of permission to path of Uri "
8260                            + grantUri);
8261                }
8262            }
8263        }
8264
8265        // Third...  does the caller itself have permission to access
8266        // this uri?
8267        final int callingAppId = UserHandle.getAppId(callingUid);
8268        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8269            Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8270                    + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8271            return -1;
8272        } else {
8273            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8274                // Require they hold a strong enough Uri permission
8275                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8276                    throw new SecurityException("Uid " + callingUid
8277                            + " does not have permission to uri " + grantUri);
8278                }
8279            }
8280        }
8281        return targetUid;
8282    }
8283
8284    /**
8285     * @param uri This uri must NOT contain an embedded userId.
8286     * @param userId The userId in which the uri is to be resolved.
8287     */
8288    @Override
8289    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8290            final int modeFlags, int userId) {
8291        enforceNotIsolatedCaller("checkGrantUriPermission");
8292        synchronized(this) {
8293            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8294                    new GrantUri(userId, uri, false), modeFlags, -1);
8295        }
8296    }
8297
8298    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8299            final int modeFlags, UriPermissionOwner owner) {
8300        if (!Intent.isAccessUriMode(modeFlags)) {
8301            return;
8302        }
8303
8304        // So here we are: the caller has the assumed permission
8305        // to the uri, and the target doesn't.  Let's now give this to
8306        // the target.
8307
8308        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8309                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8310
8311        final String authority = grantUri.uri.getAuthority();
8312        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8313                MATCH_DEBUG_TRIAGED_MISSING);
8314        if (pi == null) {
8315            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8316            return;
8317        }
8318
8319        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8320            grantUri.prefix = true;
8321        }
8322        final UriPermission perm = findOrCreateUriPermissionLocked(
8323                pi.packageName, targetPkg, targetUid, grantUri);
8324        perm.grantModes(modeFlags, owner);
8325    }
8326
8327    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8328            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8329        if (targetPkg == null) {
8330            throw new NullPointerException("targetPkg");
8331        }
8332        int targetUid;
8333        final IPackageManager pm = AppGlobals.getPackageManager();
8334        try {
8335            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8336        } catch (RemoteException ex) {
8337            return;
8338        }
8339
8340        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8341                targetUid);
8342        if (targetUid < 0) {
8343            return;
8344        }
8345
8346        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8347                owner);
8348    }
8349
8350    static class NeededUriGrants extends ArrayList<GrantUri> {
8351        final String targetPkg;
8352        final int targetUid;
8353        final int flags;
8354
8355        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8356            this.targetPkg = targetPkg;
8357            this.targetUid = targetUid;
8358            this.flags = flags;
8359        }
8360    }
8361
8362    /**
8363     * Like checkGrantUriPermissionLocked, but takes an Intent.
8364     */
8365    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8366            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8367        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8368                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8369                + " clip=" + (intent != null ? intent.getClipData() : null)
8370                + " from " + intent + "; flags=0x"
8371                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8372
8373        if (targetPkg == null) {
8374            throw new NullPointerException("targetPkg");
8375        }
8376
8377        if (intent == null) {
8378            return null;
8379        }
8380        Uri data = intent.getData();
8381        ClipData clip = intent.getClipData();
8382        if (data == null && clip == null) {
8383            return null;
8384        }
8385        // Default userId for uris in the intent (if they don't specify it themselves)
8386        int contentUserHint = intent.getContentUserHint();
8387        if (contentUserHint == UserHandle.USER_CURRENT) {
8388            contentUserHint = UserHandle.getUserId(callingUid);
8389        }
8390        final IPackageManager pm = AppGlobals.getPackageManager();
8391        int targetUid;
8392        if (needed != null) {
8393            targetUid = needed.targetUid;
8394        } else {
8395            try {
8396                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8397                        targetUserId);
8398            } catch (RemoteException ex) {
8399                return null;
8400            }
8401            if (targetUid < 0) {
8402                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8403                        "Can't grant URI permission no uid for: " + targetPkg
8404                        + " on user " + targetUserId);
8405                return null;
8406            }
8407        }
8408        if (data != null) {
8409            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8410            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8411                    targetUid);
8412            if (targetUid > 0) {
8413                if (needed == null) {
8414                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8415                }
8416                needed.add(grantUri);
8417            }
8418        }
8419        if (clip != null) {
8420            for (int i=0; i<clip.getItemCount(); i++) {
8421                Uri uri = clip.getItemAt(i).getUri();
8422                if (uri != null) {
8423                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8424                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8425                            targetUid);
8426                    if (targetUid > 0) {
8427                        if (needed == null) {
8428                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8429                        }
8430                        needed.add(grantUri);
8431                    }
8432                } else {
8433                    Intent clipIntent = clip.getItemAt(i).getIntent();
8434                    if (clipIntent != null) {
8435                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8436                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8437                        if (newNeeded != null) {
8438                            needed = newNeeded;
8439                        }
8440                    }
8441                }
8442            }
8443        }
8444
8445        return needed;
8446    }
8447
8448    /**
8449     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8450     */
8451    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8452            UriPermissionOwner owner) {
8453        if (needed != null) {
8454            for (int i=0; i<needed.size(); i++) {
8455                GrantUri grantUri = needed.get(i);
8456                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8457                        grantUri, needed.flags, owner);
8458            }
8459        }
8460    }
8461
8462    void grantUriPermissionFromIntentLocked(int callingUid,
8463            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8464        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8465                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8466        if (needed == null) {
8467            return;
8468        }
8469
8470        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8471    }
8472
8473    /**
8474     * @param uri This uri must NOT contain an embedded userId.
8475     * @param userId The userId in which the uri is to be resolved.
8476     */
8477    @Override
8478    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8479            final int modeFlags, int userId) {
8480        enforceNotIsolatedCaller("grantUriPermission");
8481        GrantUri grantUri = new GrantUri(userId, uri, false);
8482        synchronized(this) {
8483            final ProcessRecord r = getRecordForAppLocked(caller);
8484            if (r == null) {
8485                throw new SecurityException("Unable to find app for caller "
8486                        + caller
8487                        + " when granting permission to uri " + grantUri);
8488            }
8489            if (targetPkg == null) {
8490                throw new IllegalArgumentException("null target");
8491            }
8492            if (grantUri == null) {
8493                throw new IllegalArgumentException("null uri");
8494            }
8495
8496            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8497                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8498                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8499                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8500
8501            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8502                    UserHandle.getUserId(r.uid));
8503        }
8504    }
8505
8506    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8507        if (perm.modeFlags == 0) {
8508            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8509                    perm.targetUid);
8510            if (perms != null) {
8511                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8512                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8513
8514                perms.remove(perm.uri);
8515                if (perms.isEmpty()) {
8516                    mGrantedUriPermissions.remove(perm.targetUid);
8517                }
8518            }
8519        }
8520    }
8521
8522    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8523        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8524                "Revoking all granted permissions to " + grantUri);
8525
8526        final IPackageManager pm = AppGlobals.getPackageManager();
8527        final String authority = grantUri.uri.getAuthority();
8528        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8529                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8530        if (pi == null) {
8531            Slog.w(TAG, "No content provider found for permission revoke: "
8532                    + grantUri.toSafeString());
8533            return;
8534        }
8535
8536        // Does the caller have this permission on the URI?
8537        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8538            // If they don't have direct access to the URI, then revoke any
8539            // ownerless URI permissions that have been granted to them.
8540            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8541            if (perms != null) {
8542                boolean persistChanged = false;
8543                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8544                    final UriPermission perm = it.next();
8545                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8546                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8547                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8548                                "Revoking non-owned " + perm.targetUid
8549                                + " permission to " + perm.uri);
8550                        persistChanged |= perm.revokeModes(
8551                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8552                        if (perm.modeFlags == 0) {
8553                            it.remove();
8554                        }
8555                    }
8556                }
8557                if (perms.isEmpty()) {
8558                    mGrantedUriPermissions.remove(callingUid);
8559                }
8560                if (persistChanged) {
8561                    schedulePersistUriGrants();
8562                }
8563            }
8564            return;
8565        }
8566
8567        boolean persistChanged = false;
8568
8569        // Go through all of the permissions and remove any that match.
8570        int N = mGrantedUriPermissions.size();
8571        for (int i = 0; i < N; i++) {
8572            final int targetUid = mGrantedUriPermissions.keyAt(i);
8573            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8574
8575            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8576                final UriPermission perm = it.next();
8577                if (perm.uri.sourceUserId == grantUri.sourceUserId
8578                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8579                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8580                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8581                    persistChanged |= perm.revokeModes(
8582                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8583                    if (perm.modeFlags == 0) {
8584                        it.remove();
8585                    }
8586                }
8587            }
8588
8589            if (perms.isEmpty()) {
8590                mGrantedUriPermissions.remove(targetUid);
8591                N--;
8592                i--;
8593            }
8594        }
8595
8596        if (persistChanged) {
8597            schedulePersistUriGrants();
8598        }
8599    }
8600
8601    /**
8602     * @param uri This uri must NOT contain an embedded userId.
8603     * @param userId The userId in which the uri is to be resolved.
8604     */
8605    @Override
8606    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8607            int userId) {
8608        enforceNotIsolatedCaller("revokeUriPermission");
8609        synchronized(this) {
8610            final ProcessRecord r = getRecordForAppLocked(caller);
8611            if (r == null) {
8612                throw new SecurityException("Unable to find app for caller "
8613                        + caller
8614                        + " when revoking permission to uri " + uri);
8615            }
8616            if (uri == null) {
8617                Slog.w(TAG, "revokeUriPermission: null uri");
8618                return;
8619            }
8620
8621            if (!Intent.isAccessUriMode(modeFlags)) {
8622                return;
8623            }
8624
8625            final String authority = uri.getAuthority();
8626            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8627                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8628            if (pi == null) {
8629                Slog.w(TAG, "No content provider found for permission revoke: "
8630                        + uri.toSafeString());
8631                return;
8632            }
8633
8634            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8635        }
8636    }
8637
8638    /**
8639     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8640     * given package.
8641     *
8642     * @param packageName Package name to match, or {@code null} to apply to all
8643     *            packages.
8644     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8645     *            to all users.
8646     * @param persistable If persistable grants should be removed.
8647     */
8648    private void removeUriPermissionsForPackageLocked(
8649            String packageName, int userHandle, boolean persistable) {
8650        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8651            throw new IllegalArgumentException("Must narrow by either package or user");
8652        }
8653
8654        boolean persistChanged = false;
8655
8656        int N = mGrantedUriPermissions.size();
8657        for (int i = 0; i < N; i++) {
8658            final int targetUid = mGrantedUriPermissions.keyAt(i);
8659            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8660
8661            // Only inspect grants matching user
8662            if (userHandle == UserHandle.USER_ALL
8663                    || userHandle == UserHandle.getUserId(targetUid)) {
8664                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8665                    final UriPermission perm = it.next();
8666
8667                    // Only inspect grants matching package
8668                    if (packageName == null || perm.sourcePkg.equals(packageName)
8669                            || perm.targetPkg.equals(packageName)) {
8670                        // Hacky solution as part of fixing a security bug; ignore
8671                        // grants associated with DownloadManager so we don't have
8672                        // to immediately launch it to regrant the permissions
8673                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8674                                && !persistable) continue;
8675
8676                        persistChanged |= perm.revokeModes(persistable
8677                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8678
8679                        // Only remove when no modes remain; any persisted grants
8680                        // will keep this alive.
8681                        if (perm.modeFlags == 0) {
8682                            it.remove();
8683                        }
8684                    }
8685                }
8686
8687                if (perms.isEmpty()) {
8688                    mGrantedUriPermissions.remove(targetUid);
8689                    N--;
8690                    i--;
8691                }
8692            }
8693        }
8694
8695        if (persistChanged) {
8696            schedulePersistUriGrants();
8697        }
8698    }
8699
8700    @Override
8701    public IBinder newUriPermissionOwner(String name) {
8702        enforceNotIsolatedCaller("newUriPermissionOwner");
8703        synchronized(this) {
8704            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8705            return owner.getExternalTokenLocked();
8706        }
8707    }
8708
8709    @Override
8710    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8711        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8712        synchronized(this) {
8713            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8714            if (r == null) {
8715                throw new IllegalArgumentException("Activity does not exist; token="
8716                        + activityToken);
8717            }
8718            return r.getUriPermissionsLocked().getExternalTokenLocked();
8719        }
8720    }
8721    /**
8722     * @param uri This uri must NOT contain an embedded userId.
8723     * @param sourceUserId The userId in which the uri is to be resolved.
8724     * @param targetUserId The userId of the app that receives the grant.
8725     */
8726    @Override
8727    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8728            final int modeFlags, int sourceUserId, int targetUserId) {
8729        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8730                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8731                "grantUriPermissionFromOwner", null);
8732        synchronized(this) {
8733            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8734            if (owner == null) {
8735                throw new IllegalArgumentException("Unknown owner: " + token);
8736            }
8737            if (fromUid != Binder.getCallingUid()) {
8738                if (Binder.getCallingUid() != Process.myUid()) {
8739                    // Only system code can grant URI permissions on behalf
8740                    // of other users.
8741                    throw new SecurityException("nice try");
8742                }
8743            }
8744            if (targetPkg == null) {
8745                throw new IllegalArgumentException("null target");
8746            }
8747            if (uri == null) {
8748                throw new IllegalArgumentException("null uri");
8749            }
8750
8751            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8752                    modeFlags, owner, targetUserId);
8753        }
8754    }
8755
8756    /**
8757     * @param uri This uri must NOT contain an embedded userId.
8758     * @param userId The userId in which the uri is to be resolved.
8759     */
8760    @Override
8761    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8762        synchronized(this) {
8763            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8764            if (owner == null) {
8765                throw new IllegalArgumentException("Unknown owner: " + token);
8766            }
8767
8768            if (uri == null) {
8769                owner.removeUriPermissionsLocked(mode);
8770            } else {
8771                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8772                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8773            }
8774        }
8775    }
8776
8777    private void schedulePersistUriGrants() {
8778        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8779            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8780                    10 * DateUtils.SECOND_IN_MILLIS);
8781        }
8782    }
8783
8784    private void writeGrantedUriPermissions() {
8785        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8786
8787        // Snapshot permissions so we can persist without lock
8788        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8789        synchronized (this) {
8790            final int size = mGrantedUriPermissions.size();
8791            for (int i = 0; i < size; i++) {
8792                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8793                for (UriPermission perm : perms.values()) {
8794                    if (perm.persistedModeFlags != 0) {
8795                        persist.add(perm.snapshot());
8796                    }
8797                }
8798            }
8799        }
8800
8801        FileOutputStream fos = null;
8802        try {
8803            fos = mGrantFile.startWrite();
8804
8805            XmlSerializer out = new FastXmlSerializer();
8806            out.setOutput(fos, StandardCharsets.UTF_8.name());
8807            out.startDocument(null, true);
8808            out.startTag(null, TAG_URI_GRANTS);
8809            for (UriPermission.Snapshot perm : persist) {
8810                out.startTag(null, TAG_URI_GRANT);
8811                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8812                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8813                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8814                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8815                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8816                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8817                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8818                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8819                out.endTag(null, TAG_URI_GRANT);
8820            }
8821            out.endTag(null, TAG_URI_GRANTS);
8822            out.endDocument();
8823
8824            mGrantFile.finishWrite(fos);
8825        } catch (IOException e) {
8826            if (fos != null) {
8827                mGrantFile.failWrite(fos);
8828            }
8829        }
8830    }
8831
8832    private void readGrantedUriPermissionsLocked() {
8833        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8834
8835        final long now = System.currentTimeMillis();
8836
8837        FileInputStream fis = null;
8838        try {
8839            fis = mGrantFile.openRead();
8840            final XmlPullParser in = Xml.newPullParser();
8841            in.setInput(fis, StandardCharsets.UTF_8.name());
8842
8843            int type;
8844            while ((type = in.next()) != END_DOCUMENT) {
8845                final String tag = in.getName();
8846                if (type == START_TAG) {
8847                    if (TAG_URI_GRANT.equals(tag)) {
8848                        final int sourceUserId;
8849                        final int targetUserId;
8850                        final int userHandle = readIntAttribute(in,
8851                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8852                        if (userHandle != UserHandle.USER_NULL) {
8853                            // For backwards compatibility.
8854                            sourceUserId = userHandle;
8855                            targetUserId = userHandle;
8856                        } else {
8857                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8858                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8859                        }
8860                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8861                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8862                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8863                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8864                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8865                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8866
8867                        // Sanity check that provider still belongs to source package
8868                        // Both direct boot aware and unaware packages are fine as we
8869                        // will do filtering at query time to avoid multiple parsing.
8870                        final ProviderInfo pi = getProviderInfoLocked(
8871                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8872                                        | MATCH_DIRECT_BOOT_UNAWARE);
8873                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8874                            int targetUid = -1;
8875                            try {
8876                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8877                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8878                            } catch (RemoteException e) {
8879                            }
8880                            if (targetUid != -1) {
8881                                final UriPermission perm = findOrCreateUriPermissionLocked(
8882                                        sourcePkg, targetPkg, targetUid,
8883                                        new GrantUri(sourceUserId, uri, prefix));
8884                                perm.initPersistedModes(modeFlags, createdTime);
8885                            }
8886                        } else {
8887                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8888                                    + " but instead found " + pi);
8889                        }
8890                    }
8891                }
8892            }
8893        } catch (FileNotFoundException e) {
8894            // Missing grants is okay
8895        } catch (IOException e) {
8896            Slog.wtf(TAG, "Failed reading Uri grants", e);
8897        } catch (XmlPullParserException e) {
8898            Slog.wtf(TAG, "Failed reading Uri grants", e);
8899        } finally {
8900            IoUtils.closeQuietly(fis);
8901        }
8902    }
8903
8904    /**
8905     * @param uri This uri must NOT contain an embedded userId.
8906     * @param userId The userId in which the uri is to be resolved.
8907     */
8908    @Override
8909    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8910        enforceNotIsolatedCaller("takePersistableUriPermission");
8911
8912        Preconditions.checkFlagsArgument(modeFlags,
8913                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8914
8915        synchronized (this) {
8916            final int callingUid = Binder.getCallingUid();
8917            boolean persistChanged = false;
8918            GrantUri grantUri = new GrantUri(userId, uri, false);
8919
8920            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8921                    new GrantUri(userId, uri, false));
8922            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8923                    new GrantUri(userId, uri, true));
8924
8925            final boolean exactValid = (exactPerm != null)
8926                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8927            final boolean prefixValid = (prefixPerm != null)
8928                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8929
8930            if (!(exactValid || prefixValid)) {
8931                throw new SecurityException("No persistable permission grants found for UID "
8932                        + callingUid + " and Uri " + grantUri.toSafeString());
8933            }
8934
8935            if (exactValid) {
8936                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8937            }
8938            if (prefixValid) {
8939                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8940            }
8941
8942            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8943
8944            if (persistChanged) {
8945                schedulePersistUriGrants();
8946            }
8947        }
8948    }
8949
8950    /**
8951     * @param uri This uri must NOT contain an embedded userId.
8952     * @param userId The userId in which the uri is to be resolved.
8953     */
8954    @Override
8955    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8956        enforceNotIsolatedCaller("releasePersistableUriPermission");
8957
8958        Preconditions.checkFlagsArgument(modeFlags,
8959                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8960
8961        synchronized (this) {
8962            final int callingUid = Binder.getCallingUid();
8963            boolean persistChanged = false;
8964
8965            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8966                    new GrantUri(userId, uri, false));
8967            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8968                    new GrantUri(userId, uri, true));
8969            if (exactPerm == null && prefixPerm == null) {
8970                throw new SecurityException("No permission grants found for UID " + callingUid
8971                        + " and Uri " + uri.toSafeString());
8972            }
8973
8974            if (exactPerm != null) {
8975                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8976                removeUriPermissionIfNeededLocked(exactPerm);
8977            }
8978            if (prefixPerm != null) {
8979                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8980                removeUriPermissionIfNeededLocked(prefixPerm);
8981            }
8982
8983            if (persistChanged) {
8984                schedulePersistUriGrants();
8985            }
8986        }
8987    }
8988
8989    /**
8990     * Prune any older {@link UriPermission} for the given UID until outstanding
8991     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8992     *
8993     * @return if any mutations occured that require persisting.
8994     */
8995    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8996        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8997        if (perms == null) return false;
8998        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8999
9000        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9001        for (UriPermission perm : perms.values()) {
9002            if (perm.persistedModeFlags != 0) {
9003                persisted.add(perm);
9004            }
9005        }
9006
9007        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9008        if (trimCount <= 0) return false;
9009
9010        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9011        for (int i = 0; i < trimCount; i++) {
9012            final UriPermission perm = persisted.get(i);
9013
9014            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9015                    "Trimming grant created at " + perm.persistedCreateTime);
9016
9017            perm.releasePersistableModes(~0);
9018            removeUriPermissionIfNeededLocked(perm);
9019        }
9020
9021        return true;
9022    }
9023
9024    @Override
9025    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9026            String packageName, boolean incoming) {
9027        enforceNotIsolatedCaller("getPersistedUriPermissions");
9028        Preconditions.checkNotNull(packageName, "packageName");
9029
9030        final int callingUid = Binder.getCallingUid();
9031        final int callingUserId = UserHandle.getUserId(callingUid);
9032        final IPackageManager pm = AppGlobals.getPackageManager();
9033        try {
9034            final int packageUid = pm.getPackageUid(packageName,
9035                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9036            if (packageUid != callingUid) {
9037                throw new SecurityException(
9038                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9039            }
9040        } catch (RemoteException e) {
9041            throw new SecurityException("Failed to verify package name ownership");
9042        }
9043
9044        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9045        synchronized (this) {
9046            if (incoming) {
9047                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9048                        callingUid);
9049                if (perms == null) {
9050                    Slog.w(TAG, "No permission grants found for " + packageName);
9051                } else {
9052                    for (UriPermission perm : perms.values()) {
9053                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9054                            result.add(perm.buildPersistedPublicApiObject());
9055                        }
9056                    }
9057                }
9058            } else {
9059                final int size = mGrantedUriPermissions.size();
9060                for (int i = 0; i < size; i++) {
9061                    final ArrayMap<GrantUri, UriPermission> perms =
9062                            mGrantedUriPermissions.valueAt(i);
9063                    for (UriPermission perm : perms.values()) {
9064                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9065                            result.add(perm.buildPersistedPublicApiObject());
9066                        }
9067                    }
9068                }
9069            }
9070        }
9071        return new ParceledListSlice<android.content.UriPermission>(result);
9072    }
9073
9074    @Override
9075    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9076            String packageName, int userId) {
9077        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9078                "getGrantedUriPermissions");
9079
9080        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9081        synchronized (this) {
9082            final int size = mGrantedUriPermissions.size();
9083            for (int i = 0; i < size; i++) {
9084                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9085                for (UriPermission perm : perms.values()) {
9086                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9087                            && perm.persistedModeFlags != 0) {
9088                        result.add(perm.buildPersistedPublicApiObject());
9089                    }
9090                }
9091            }
9092        }
9093        return new ParceledListSlice<android.content.UriPermission>(result);
9094    }
9095
9096    @Override
9097    public void clearGrantedUriPermissions(String packageName, int userId) {
9098        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9099                "clearGrantedUriPermissions");
9100        removeUriPermissionsForPackageLocked(packageName, userId, true);
9101    }
9102
9103    @Override
9104    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9105        synchronized (this) {
9106            ProcessRecord app =
9107                who != null ? getRecordForAppLocked(who) : null;
9108            if (app == null) return;
9109
9110            Message msg = Message.obtain();
9111            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9112            msg.obj = app;
9113            msg.arg1 = waiting ? 1 : 0;
9114            mUiHandler.sendMessage(msg);
9115        }
9116    }
9117
9118    @Override
9119    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9120        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9121        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9122        outInfo.availMem = Process.getFreeMemory();
9123        outInfo.totalMem = Process.getTotalMemory();
9124        outInfo.threshold = homeAppMem;
9125        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9126        outInfo.hiddenAppThreshold = cachedAppMem;
9127        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9128                ProcessList.SERVICE_ADJ);
9129        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9130                ProcessList.VISIBLE_APP_ADJ);
9131        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9132                ProcessList.FOREGROUND_APP_ADJ);
9133    }
9134
9135    // =========================================================
9136    // TASK MANAGEMENT
9137    // =========================================================
9138
9139    @Override
9140    public List<IBinder> getAppTasks(String callingPackage) {
9141        int callingUid = Binder.getCallingUid();
9142        long ident = Binder.clearCallingIdentity();
9143
9144        synchronized(this) {
9145            ArrayList<IBinder> list = new ArrayList<IBinder>();
9146            try {
9147                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9148
9149                final int N = mRecentTasks.size();
9150                for (int i = 0; i < N; i++) {
9151                    TaskRecord tr = mRecentTasks.get(i);
9152                    // Skip tasks that do not match the caller.  We don't need to verify
9153                    // callingPackage, because we are also limiting to callingUid and know
9154                    // that will limit to the correct security sandbox.
9155                    if (tr.effectiveUid != callingUid) {
9156                        continue;
9157                    }
9158                    Intent intent = tr.getBaseIntent();
9159                    if (intent == null ||
9160                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9161                        continue;
9162                    }
9163                    ActivityManager.RecentTaskInfo taskInfo =
9164                            createRecentTaskInfoFromTaskRecord(tr);
9165                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9166                    list.add(taskImpl.asBinder());
9167                }
9168            } finally {
9169                Binder.restoreCallingIdentity(ident);
9170            }
9171            return list;
9172        }
9173    }
9174
9175    @Override
9176    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9177        final int callingUid = Binder.getCallingUid();
9178        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9179
9180        synchronized(this) {
9181            if (DEBUG_ALL) Slog.v(
9182                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9183
9184            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9185                    callingUid);
9186
9187            // TODO: Improve with MRU list from all ActivityStacks.
9188            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9189        }
9190
9191        return list;
9192    }
9193
9194    /**
9195     * Creates a new RecentTaskInfo from a TaskRecord.
9196     */
9197    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9198        // Update the task description to reflect any changes in the task stack
9199        tr.updateTaskDescription();
9200
9201        // Compose the recent task info
9202        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9203        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9204        rti.persistentId = tr.taskId;
9205        rti.baseIntent = new Intent(tr.getBaseIntent());
9206        rti.origActivity = tr.origActivity;
9207        rti.realActivity = tr.realActivity;
9208        rti.description = tr.lastDescription;
9209        rti.stackId = tr.getStackId();
9210        rti.userId = tr.userId;
9211        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9212        rti.firstActiveTime = tr.firstActiveTime;
9213        rti.lastActiveTime = tr.lastActiveTime;
9214        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9215        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9216        rti.numActivities = 0;
9217        if (tr.mBounds != null) {
9218            rti.bounds = new Rect(tr.mBounds);
9219        }
9220        rti.isDockable = tr.canGoInDockedStack();
9221        rti.resizeMode = tr.mResizeMode;
9222
9223        ActivityRecord base = null;
9224        ActivityRecord top = null;
9225        ActivityRecord tmp;
9226
9227        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9228            tmp = tr.mActivities.get(i);
9229            if (tmp.finishing) {
9230                continue;
9231            }
9232            base = tmp;
9233            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9234                top = base;
9235            }
9236            rti.numActivities++;
9237        }
9238
9239        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9240        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9241
9242        return rti;
9243    }
9244
9245    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9246        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9247                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9248        if (!allowed) {
9249            if (checkPermission(android.Manifest.permission.GET_TASKS,
9250                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9251                // Temporary compatibility: some existing apps on the system image may
9252                // still be requesting the old permission and not switched to the new
9253                // one; if so, we'll still allow them full access.  This means we need
9254                // to see if they are holding the old permission and are a system app.
9255                try {
9256                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9257                        allowed = true;
9258                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9259                                + " is using old GET_TASKS but privileged; allowing");
9260                    }
9261                } catch (RemoteException e) {
9262                }
9263            }
9264        }
9265        if (!allowed) {
9266            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9267                    + " does not hold REAL_GET_TASKS; limiting output");
9268        }
9269        return allowed;
9270    }
9271
9272    @Override
9273    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9274            int userId) {
9275        final int callingUid = Binder.getCallingUid();
9276        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9277                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9278
9279        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9280        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9281        synchronized (this) {
9282            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9283                    callingUid);
9284            final boolean detailed = checkCallingPermission(
9285                    android.Manifest.permission.GET_DETAILED_TASKS)
9286                    == PackageManager.PERMISSION_GRANTED;
9287
9288            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9289                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9290                return ParceledListSlice.emptyList();
9291            }
9292            mRecentTasks.loadUserRecentsLocked(userId);
9293
9294            final int recentsCount = mRecentTasks.size();
9295            ArrayList<ActivityManager.RecentTaskInfo> res =
9296                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9297
9298            final Set<Integer> includedUsers;
9299            if (includeProfiles) {
9300                includedUsers = mUserController.getProfileIds(userId);
9301            } else {
9302                includedUsers = new HashSet<>();
9303            }
9304            includedUsers.add(Integer.valueOf(userId));
9305
9306            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9307                TaskRecord tr = mRecentTasks.get(i);
9308                // Only add calling user or related users recent tasks
9309                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9310                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9311                    continue;
9312                }
9313
9314                if (tr.realActivitySuspended) {
9315                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9316                    continue;
9317                }
9318
9319                // Return the entry if desired by the caller.  We always return
9320                // the first entry, because callers always expect this to be the
9321                // foreground app.  We may filter others if the caller has
9322                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9323                // we should exclude the entry.
9324
9325                if (i == 0
9326                        || withExcluded
9327                        || (tr.intent == null)
9328                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9329                                == 0)) {
9330                    if (!allowed) {
9331                        // If the caller doesn't have the GET_TASKS permission, then only
9332                        // allow them to see a small subset of tasks -- their own and home.
9333                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9334                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9335                            continue;
9336                        }
9337                    }
9338                    final ActivityStack stack = tr.getStack();
9339                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9340                        if (stack != null && stack.isHomeOrRecentsStack()) {
9341                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9342                                    "Skipping, home or recents stack task: " + tr);
9343                            continue;
9344                        }
9345                    }
9346                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9347                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9348                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9349                                    "Skipping, top task in docked stack: " + tr);
9350                            continue;
9351                        }
9352                    }
9353                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9354                        if (stack != null && stack.isPinnedStack()) {
9355                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9356                                    "Skipping, pinned stack task: " + tr);
9357                            continue;
9358                        }
9359                    }
9360                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9361                        // Don't include auto remove tasks that are finished or finishing.
9362                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9363                                "Skipping, auto-remove without activity: " + tr);
9364                        continue;
9365                    }
9366                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9367                            && !tr.isAvailable) {
9368                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9369                                "Skipping, unavail real act: " + tr);
9370                        continue;
9371                    }
9372
9373                    if (!tr.mUserSetupComplete) {
9374                        // Don't include task launched while user is not done setting-up.
9375                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9376                                "Skipping, user setup not complete: " + tr);
9377                        continue;
9378                    }
9379
9380                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9381                    if (!detailed) {
9382                        rti.baseIntent.replaceExtras((Bundle)null);
9383                    }
9384
9385                    res.add(rti);
9386                    maxNum--;
9387                }
9388            }
9389            return new ParceledListSlice<>(res);
9390        }
9391    }
9392
9393    @Override
9394    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9395        synchronized (this) {
9396            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9397                    "getTaskThumbnail()");
9398            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9399                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9400            if (tr != null) {
9401                return tr.getTaskThumbnailLocked();
9402            }
9403        }
9404        return null;
9405    }
9406
9407    @Override
9408    public int addAppTask(IBinder activityToken, Intent intent,
9409            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9410        final int callingUid = Binder.getCallingUid();
9411        final long callingIdent = Binder.clearCallingIdentity();
9412
9413        try {
9414            synchronized (this) {
9415                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9416                if (r == null) {
9417                    throw new IllegalArgumentException("Activity does not exist; token="
9418                            + activityToken);
9419                }
9420                ComponentName comp = intent.getComponent();
9421                if (comp == null) {
9422                    throw new IllegalArgumentException("Intent " + intent
9423                            + " must specify explicit component");
9424                }
9425                if (thumbnail.getWidth() != mThumbnailWidth
9426                        || thumbnail.getHeight() != mThumbnailHeight) {
9427                    throw new IllegalArgumentException("Bad thumbnail size: got "
9428                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9429                            + mThumbnailWidth + "x" + mThumbnailHeight);
9430                }
9431                if (intent.getSelector() != null) {
9432                    intent.setSelector(null);
9433                }
9434                if (intent.getSourceBounds() != null) {
9435                    intent.setSourceBounds(null);
9436                }
9437                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9438                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9439                        // The caller has added this as an auto-remove task...  that makes no
9440                        // sense, so turn off auto-remove.
9441                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9442                    }
9443                }
9444                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9445                    mLastAddedTaskActivity = null;
9446                }
9447                ActivityInfo ainfo = mLastAddedTaskActivity;
9448                if (ainfo == null) {
9449                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9450                            comp, 0, UserHandle.getUserId(callingUid));
9451                    if (ainfo.applicationInfo.uid != callingUid) {
9452                        throw new SecurityException(
9453                                "Can't add task for another application: target uid="
9454                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9455                    }
9456                }
9457
9458                TaskRecord task = new TaskRecord(this,
9459                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9460                        ainfo, intent, description, new TaskThumbnailInfo());
9461
9462                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9463                if (trimIdx >= 0) {
9464                    // If this would have caused a trim, then we'll abort because that
9465                    // means it would be added at the end of the list but then just removed.
9466                    return INVALID_TASK_ID;
9467                }
9468
9469                final int N = mRecentTasks.size();
9470                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9471                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9472                    tr.removedFromRecents();
9473                }
9474
9475                task.inRecents = true;
9476                mRecentTasks.add(task);
9477                r.getStack().addTask(task, false, "addAppTask");
9478
9479                task.setLastThumbnailLocked(thumbnail);
9480                task.freeLastThumbnail();
9481                return task.taskId;
9482            }
9483        } finally {
9484            Binder.restoreCallingIdentity(callingIdent);
9485        }
9486    }
9487
9488    @Override
9489    public Point getAppTaskThumbnailSize() {
9490        synchronized (this) {
9491            return new Point(mThumbnailWidth,  mThumbnailHeight);
9492        }
9493    }
9494
9495    @Override
9496    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9497        synchronized (this) {
9498            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9499            if (r != null) {
9500                r.setTaskDescription(td);
9501                r.task.updateTaskDescription();
9502                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9503            }
9504        }
9505    }
9506
9507    @Override
9508    public void setTaskResizeable(int taskId, int resizeableMode) {
9509        synchronized (this) {
9510            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9511                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9512            if (task == null) {
9513                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9514                return;
9515            }
9516            if (task.mResizeMode != resizeableMode) {
9517                task.mResizeMode = resizeableMode;
9518                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9519                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9520                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9521            }
9522        }
9523    }
9524
9525    @Override
9526    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9527        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9528        long ident = Binder.clearCallingIdentity();
9529        try {
9530            synchronized (this) {
9531                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9532                if (task == null) {
9533                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9534                    return;
9535                }
9536                // Place the task in the right stack if it isn't there already based on
9537                // the requested bounds.
9538                // The stack transition logic is:
9539                // - a null bounds on a freeform task moves that task to fullscreen
9540                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9541                //   that task to freeform
9542                // - otherwise the task is not moved
9543                int stackId = task.getStackId();
9544                if (!StackId.isTaskResizeAllowed(stackId)) {
9545                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9546                }
9547                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9548                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9549                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9550                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9551                }
9552                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9553                if (stackId != task.getStackId()) {
9554                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9555                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9556                    preserveWindow = false;
9557                }
9558
9559                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9560                        false /* deferResume */);
9561            }
9562        } finally {
9563            Binder.restoreCallingIdentity(ident);
9564        }
9565    }
9566
9567    @Override
9568    public Rect getTaskBounds(int taskId) {
9569        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9570        long ident = Binder.clearCallingIdentity();
9571        Rect rect = new Rect();
9572        try {
9573            synchronized (this) {
9574                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9575                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9576                if (task == null) {
9577                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9578                    return rect;
9579                }
9580                if (task.getStack() != null) {
9581                    // Return the bounds from window manager since it will be adjusted for various
9582                    // things like the presense of a docked stack for tasks that aren't resizeable.
9583                    mWindowManager.getTaskBounds(task.taskId, rect);
9584                } else {
9585                    // Task isn't in window manager yet since it isn't associated with a stack.
9586                    // Return the persist value from activity manager
9587                    if (task.mBounds != null) {
9588                        rect.set(task.mBounds);
9589                    } else if (task.mLastNonFullscreenBounds != null) {
9590                        rect.set(task.mLastNonFullscreenBounds);
9591                    }
9592                }
9593            }
9594        } finally {
9595            Binder.restoreCallingIdentity(ident);
9596        }
9597        return rect;
9598    }
9599
9600    @Override
9601    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9602        if (userId != UserHandle.getCallingUserId()) {
9603            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9604                    "getTaskDescriptionIcon");
9605        }
9606        final File passedIconFile = new File(filePath);
9607        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9608                passedIconFile.getName());
9609        if (!legitIconFile.getPath().equals(filePath)
9610                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9611            throw new IllegalArgumentException("Bad file path: " + filePath
9612                    + " passed for userId " + userId);
9613        }
9614        return mRecentTasks.getTaskDescriptionIcon(filePath);
9615    }
9616
9617    @Override
9618    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9619            throws RemoteException {
9620        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9621        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9622                activityOptions.getCustomInPlaceResId() == 0) {
9623            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9624                    "with valid animation");
9625        }
9626        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9627        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9628                activityOptions.getCustomInPlaceResId());
9629        mWindowManager.executeAppTransition();
9630    }
9631
9632    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9633        // Remove all tasks with activities in the specified package from the list of recent tasks
9634        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9635            TaskRecord tr = mRecentTasks.get(i);
9636            if (tr.userId != userId) continue;
9637
9638            ComponentName cn = tr.intent.getComponent();
9639            if (cn != null && cn.getPackageName().equals(packageName)) {
9640                // If the package name matches, remove the task.
9641                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9642            }
9643        }
9644    }
9645
9646    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9647            int userId) {
9648
9649        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9650            TaskRecord tr = mRecentTasks.get(i);
9651            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9652                continue;
9653            }
9654
9655            ComponentName cn = tr.intent.getComponent();
9656            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9657                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9658            if (sameComponent) {
9659                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9660            }
9661        }
9662    }
9663
9664    @Override
9665    public void removeStack(int stackId) {
9666        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9667        if (StackId.isHomeOrRecentsStack(stackId)) {
9668            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
9669        }
9670
9671        synchronized (this) {
9672            final long ident = Binder.clearCallingIdentity();
9673            try {
9674                mStackSupervisor.removeStackLocked(stackId);
9675            } finally {
9676                Binder.restoreCallingIdentity(ident);
9677            }
9678        }
9679    }
9680
9681    @Override
9682    public void moveStackToDisplay(int stackId, int displayId) {
9683        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
9684
9685        synchronized (this) {
9686            final long ident = Binder.clearCallingIdentity();
9687            try {
9688                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
9689                        + " to displayId=" + displayId);
9690                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId);
9691            } finally {
9692                Binder.restoreCallingIdentity(ident);
9693            }
9694        }
9695    }
9696
9697    @Override
9698    public boolean removeTask(int taskId) {
9699        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9700        synchronized (this) {
9701            final long ident = Binder.clearCallingIdentity();
9702            try {
9703                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9704            } finally {
9705                Binder.restoreCallingIdentity(ident);
9706            }
9707        }
9708    }
9709
9710    /**
9711     * TODO: Add mController hook
9712     */
9713    @Override
9714    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9715        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9716
9717        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9718        synchronized(this) {
9719            moveTaskToFrontLocked(taskId, flags, bOptions);
9720        }
9721    }
9722
9723    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9724        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9725
9726        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9727                Binder.getCallingUid(), -1, -1, "Task to front")) {
9728            ActivityOptions.abort(options);
9729            return;
9730        }
9731        final long origId = Binder.clearCallingIdentity();
9732        try {
9733            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9734            if (task == null) {
9735                Slog.d(TAG, "Could not find task for id: "+ taskId);
9736                return;
9737            }
9738            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9739                mStackSupervisor.showLockTaskToast();
9740                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9741                return;
9742            }
9743            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9744            if (prev != null && prev.isRecentsActivity()) {
9745                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9746            }
9747            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9748                    false /* forceNonResizable */);
9749        } finally {
9750            Binder.restoreCallingIdentity(origId);
9751        }
9752        ActivityOptions.abort(options);
9753    }
9754
9755    /**
9756     * Moves an activity, and all of the other activities within the same task, to the bottom
9757     * of the history stack.  The activity's order within the task is unchanged.
9758     *
9759     * @param token A reference to the activity we wish to move
9760     * @param nonRoot If false then this only works if the activity is the root
9761     *                of a task; if true it will work for any activity in a task.
9762     * @return Returns true if the move completed, false if not.
9763     */
9764    @Override
9765    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9766        enforceNotIsolatedCaller("moveActivityTaskToBack");
9767        synchronized(this) {
9768            final long origId = Binder.clearCallingIdentity();
9769            try {
9770                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9771                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9772                if (task != null) {
9773                    if (mStackSupervisor.isLockedTask(task)) {
9774                        mStackSupervisor.showLockTaskToast();
9775                        return false;
9776                    }
9777                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9778                }
9779            } finally {
9780                Binder.restoreCallingIdentity(origId);
9781            }
9782        }
9783        return false;
9784    }
9785
9786    @Override
9787    public void moveTaskBackwards(int task) {
9788        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9789                "moveTaskBackwards()");
9790
9791        synchronized(this) {
9792            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9793                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9794                return;
9795            }
9796            final long origId = Binder.clearCallingIdentity();
9797            moveTaskBackwardsLocked(task);
9798            Binder.restoreCallingIdentity(origId);
9799        }
9800    }
9801
9802    private final void moveTaskBackwardsLocked(int task) {
9803        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9804    }
9805
9806    @Override
9807    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9808            IActivityContainerCallback callback) throws RemoteException {
9809        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9810        synchronized (this) {
9811            if (parentActivityToken == null) {
9812                throw new IllegalArgumentException("parent token must not be null");
9813            }
9814            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9815            if (r == null) {
9816                return null;
9817            }
9818            if (callback == null) {
9819                throw new IllegalArgumentException("callback must not be null");
9820            }
9821            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9822        }
9823    }
9824
9825    @Override
9826    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9827        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9828        synchronized (this) {
9829            final int stackId = mStackSupervisor.getNextStackId();
9830            final ActivityStack stack =
9831                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9832            if (stack == null) {
9833                return null;
9834            }
9835            return stack.mActivityContainer;
9836        }
9837    }
9838
9839    @Override
9840    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9841        synchronized (this) {
9842            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9843            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9844                return stack.mActivityContainer.getDisplayId();
9845            }
9846            return DEFAULT_DISPLAY;
9847        }
9848    }
9849
9850    @Override
9851    public int getActivityStackId(IBinder token) throws RemoteException {
9852        synchronized (this) {
9853            ActivityStack stack = ActivityRecord.getStackLocked(token);
9854            if (stack == null) {
9855                return INVALID_STACK_ID;
9856            }
9857            return stack.mStackId;
9858        }
9859    }
9860
9861    @Override
9862    public void exitFreeformMode(IBinder token) throws RemoteException {
9863        synchronized (this) {
9864            long ident = Binder.clearCallingIdentity();
9865            try {
9866                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9867                if (r == null) {
9868                    throw new IllegalArgumentException(
9869                            "exitFreeformMode: No activity record matching token=" + token);
9870                }
9871                final ActivityStack stack = r.getStackLocked(token);
9872                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9873                    throw new IllegalStateException(
9874                            "exitFreeformMode: You can only go fullscreen from freeform.");
9875                }
9876                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9877                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9878                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9879            } finally {
9880                Binder.restoreCallingIdentity(ident);
9881            }
9882        }
9883    }
9884
9885    @Override
9886    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9887        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9888        if (StackId.isHomeOrRecentsStack(stackId)) {
9889            throw new IllegalArgumentException(
9890                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
9891        }
9892        synchronized (this) {
9893            long ident = Binder.clearCallingIdentity();
9894            try {
9895                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9896                        + " to stackId=" + stackId + " toTop=" + toTop);
9897                if (stackId == DOCKED_STACK_ID) {
9898                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9899                            null /* initialBounds */);
9900                }
9901                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9902                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9903                if (result && stackId == DOCKED_STACK_ID) {
9904                    // If task moved to docked stack - show recents if needed.
9905                    mWindowManager.showRecentApps(false /* fromHome */);
9906                }
9907            } finally {
9908                Binder.restoreCallingIdentity(ident);
9909            }
9910        }
9911    }
9912
9913    @Override
9914    public void swapDockedAndFullscreenStack() throws RemoteException {
9915        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9916        synchronized (this) {
9917            long ident = Binder.clearCallingIdentity();
9918            try {
9919                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9920                        FULLSCREEN_WORKSPACE_STACK_ID);
9921                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9922                        : null;
9923                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9924                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9925                        : null;
9926                if (topTask == null || tasks == null || tasks.size() == 0) {
9927                    Slog.w(TAG,
9928                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9929                    return;
9930                }
9931
9932                // TODO: App transition
9933                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9934
9935                // Defer the resume so resume/pausing while moving stacks is dangerous.
9936                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9937                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9938                        ANIMATE, true /* deferResume */);
9939                final int size = tasks.size();
9940                for (int i = 0; i < size; i++) {
9941                    final int id = tasks.get(i).taskId;
9942                    if (id == topTask.taskId) {
9943                        continue;
9944                    }
9945                    mStackSupervisor.moveTaskToStackLocked(id,
9946                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9947                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9948                }
9949
9950                // Because we deferred the resume, to avoid conflicts with stack switches while
9951                // resuming, we need to do it after all the tasks are moved.
9952                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9953                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9954
9955                mWindowManager.executeAppTransition();
9956            } finally {
9957                Binder.restoreCallingIdentity(ident);
9958            }
9959        }
9960    }
9961
9962    /**
9963     * Moves the input task to the docked stack.
9964     *
9965     * @param taskId Id of task to move.
9966     * @param createMode The mode the docked stack should be created in if it doesn't exist
9967     *                   already. See
9968     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9969     *                   and
9970     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9971     * @param toTop If the task and stack should be moved to the top.
9972     * @param animate Whether we should play an animation for the moving the task
9973     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9974     *                      docked stack. Pass {@code null} to use default bounds.
9975     */
9976    @Override
9977    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9978            Rect initialBounds, boolean moveHomeStackFront) {
9979        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9980        synchronized (this) {
9981            long ident = Binder.clearCallingIdentity();
9982            try {
9983                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9984                        + " to createMode=" + createMode + " toTop=" + toTop);
9985                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9986                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9987                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9988                        animate, DEFER_RESUME);
9989                if (moved) {
9990                    if (moveHomeStackFront) {
9991                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9992                    }
9993                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9994                }
9995                return moved;
9996            } finally {
9997                Binder.restoreCallingIdentity(ident);
9998            }
9999        }
10000    }
10001
10002    /**
10003     * Moves the top activity in the input stackId to the pinned stack.
10004     *
10005     * @param stackId Id of stack to move the top activity to pinned stack.
10006     * @param bounds Bounds to use for pinned stack.
10007     *
10008     * @return True if the top activity of the input stack was successfully moved to the pinned
10009     *          stack.
10010     */
10011    @Override
10012    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10013        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10014        synchronized (this) {
10015            if (!mSupportsPictureInPicture) {
10016                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10017                        + "Device doesn't support picture-in-pciture mode");
10018            }
10019
10020            long ident = Binder.clearCallingIdentity();
10021            try {
10022                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10023            } finally {
10024                Binder.restoreCallingIdentity(ident);
10025            }
10026        }
10027    }
10028
10029    @Override
10030    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10031            boolean preserveWindows, boolean animate, int animationDuration) {
10032        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10033        long ident = Binder.clearCallingIdentity();
10034        try {
10035            synchronized (this) {
10036                if (animate) {
10037                    if (stackId == PINNED_STACK_ID) {
10038                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10039                    } else {
10040                        throw new IllegalArgumentException("Stack: " + stackId
10041                                + " doesn't support animated resize.");
10042                    }
10043                } else {
10044                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10045                            null /* tempTaskInsetBounds */, preserveWindows,
10046                            allowResizeInDockedMode, !DEFER_RESUME);
10047                }
10048            }
10049        } finally {
10050            Binder.restoreCallingIdentity(ident);
10051        }
10052    }
10053
10054    @Override
10055    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10056            Rect tempDockedTaskInsetBounds,
10057            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10058        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10059                "resizeDockedStack()");
10060        long ident = Binder.clearCallingIdentity();
10061        try {
10062            synchronized (this) {
10063                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10064                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10065                        PRESERVE_WINDOWS);
10066            }
10067        } finally {
10068            Binder.restoreCallingIdentity(ident);
10069        }
10070    }
10071
10072    @Override
10073    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10074        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10075                "resizePinnedStack()");
10076        final long ident = Binder.clearCallingIdentity();
10077        try {
10078            synchronized (this) {
10079                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10080            }
10081        } finally {
10082            Binder.restoreCallingIdentity(ident);
10083        }
10084    }
10085
10086    /**
10087     * Try to place task to provided position. The final position might be different depending on
10088     * current user and stacks state. The task will be moved to target stack if it's currently in
10089     * different stack.
10090     */
10091    @Override
10092    public void positionTaskInStack(int taskId, int stackId, int position) {
10093        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10094        if (StackId.isHomeOrRecentsStack(stackId)) {
10095            throw new IllegalArgumentException(
10096                    "positionTaskInStack: Attempt to change the position of task "
10097                    + taskId + " in/to home/recents stack");
10098        }
10099        synchronized (this) {
10100            long ident = Binder.clearCallingIdentity();
10101            try {
10102                if (DEBUG_STACK) Slog.d(TAG_STACK,
10103                        "positionTaskInStack: positioning task=" + taskId
10104                        + " in stackId=" + stackId + " at position=" + position);
10105                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10106            } finally {
10107                Binder.restoreCallingIdentity(ident);
10108            }
10109        }
10110    }
10111
10112    @Override
10113    public List<StackInfo> getAllStackInfos() {
10114        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10115        long ident = Binder.clearCallingIdentity();
10116        try {
10117            synchronized (this) {
10118                return mStackSupervisor.getAllStackInfosLocked();
10119            }
10120        } finally {
10121            Binder.restoreCallingIdentity(ident);
10122        }
10123    }
10124
10125    @Override
10126    public StackInfo getStackInfo(int stackId) {
10127        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10128        long ident = Binder.clearCallingIdentity();
10129        try {
10130            synchronized (this) {
10131                return mStackSupervisor.getStackInfoLocked(stackId);
10132            }
10133        } finally {
10134            Binder.restoreCallingIdentity(ident);
10135        }
10136    }
10137
10138    @Override
10139    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10140        synchronized(this) {
10141            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10142        }
10143    }
10144
10145    @Override
10146    public void updateDeviceOwner(String packageName) {
10147        final int callingUid = Binder.getCallingUid();
10148        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10149            throw new SecurityException("updateDeviceOwner called from non-system process");
10150        }
10151        synchronized (this) {
10152            mDeviceOwnerName = packageName;
10153        }
10154    }
10155
10156    @Override
10157    public void updateLockTaskPackages(int userId, String[] packages) {
10158        final int callingUid = Binder.getCallingUid();
10159        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10160            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10161                    "updateLockTaskPackages()");
10162        }
10163        synchronized (this) {
10164            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10165                    Arrays.toString(packages));
10166            mLockTaskPackages.put(userId, packages);
10167            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10168        }
10169    }
10170
10171
10172    void startLockTaskModeLocked(TaskRecord task) {
10173        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10174        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10175            return;
10176        }
10177
10178        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10179        // is initiated by system after the pinning request was shown and locked mode is initiated
10180        // by an authorized app directly
10181        final int callingUid = Binder.getCallingUid();
10182        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10183        long ident = Binder.clearCallingIdentity();
10184        try {
10185            if (!isSystemInitiated) {
10186                task.mLockTaskUid = callingUid;
10187                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10188                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10189                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10190                    StatusBarManagerInternal statusBarManager =
10191                            LocalServices.getService(StatusBarManagerInternal.class);
10192                    if (statusBarManager != null) {
10193                        statusBarManager.showScreenPinningRequest(task.taskId);
10194                    }
10195                    return;
10196                }
10197
10198                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10199                if (stack == null || task != stack.topTask()) {
10200                    throw new IllegalArgumentException("Invalid task, not in foreground");
10201                }
10202            }
10203            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10204                    "Locking fully");
10205            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10206                    ActivityManager.LOCK_TASK_MODE_PINNED :
10207                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10208                    "startLockTask", true);
10209        } finally {
10210            Binder.restoreCallingIdentity(ident);
10211        }
10212    }
10213
10214    @Override
10215    public void startLockTaskModeById(int taskId) {
10216        synchronized (this) {
10217            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10218            if (task != null) {
10219                startLockTaskModeLocked(task);
10220            }
10221        }
10222    }
10223
10224    @Override
10225    public void startLockTaskModeByToken(IBinder token) {
10226        synchronized (this) {
10227            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10228            if (r == null) {
10229                return;
10230            }
10231            final TaskRecord task = r.task;
10232            if (task != null) {
10233                startLockTaskModeLocked(task);
10234            }
10235        }
10236    }
10237
10238    @Override
10239    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10240        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10241        // This makes inner call to look as if it was initiated by system.
10242        long ident = Binder.clearCallingIdentity();
10243        try {
10244            synchronized (this) {
10245                startLockTaskModeById(taskId);
10246            }
10247        } finally {
10248            Binder.restoreCallingIdentity(ident);
10249        }
10250    }
10251
10252    @Override
10253    public void stopLockTaskMode() {
10254        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10255        if (lockTask == null) {
10256            // Our work here is done.
10257            return;
10258        }
10259
10260        final int callingUid = Binder.getCallingUid();
10261        final int lockTaskUid = lockTask.mLockTaskUid;
10262        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10263        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10264            // Done.
10265            return;
10266        } else {
10267            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10268            // It is possible lockTaskMode was started by the system process because
10269            // android:lockTaskMode is set to a locking value in the application manifest
10270            // instead of the app calling startLockTaskMode. In this case
10271            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10272            // {@link TaskRecord.effectiveUid} instead. Also caller with
10273            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10274            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10275                    && callingUid != lockTaskUid
10276                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10277                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10278                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10279            }
10280        }
10281        long ident = Binder.clearCallingIdentity();
10282        try {
10283            Log.d(TAG, "stopLockTaskMode");
10284            // Stop lock task
10285            synchronized (this) {
10286                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10287                        "stopLockTask", true);
10288            }
10289            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10290            if (tm != null) {
10291                tm.showInCallScreen(false);
10292            }
10293        } finally {
10294            Binder.restoreCallingIdentity(ident);
10295        }
10296    }
10297
10298    /**
10299     * This API should be called by SystemUI only when user perform certain action to dismiss
10300     * lock task mode. We should only dismiss pinned lock task mode in this case.
10301     */
10302    @Override
10303    public void stopSystemLockTaskMode() throws RemoteException {
10304        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10305            stopLockTaskMode();
10306        } else {
10307            mStackSupervisor.showLockTaskToast();
10308        }
10309    }
10310
10311    @Override
10312    public boolean isInLockTaskMode() {
10313        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10314    }
10315
10316    @Override
10317    public int getLockTaskModeState() {
10318        synchronized (this) {
10319            return mStackSupervisor.getLockTaskModeState();
10320        }
10321    }
10322
10323    @Override
10324    public void showLockTaskEscapeMessage(IBinder token) {
10325        synchronized (this) {
10326            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10327            if (r == null) {
10328                return;
10329            }
10330            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10331        }
10332    }
10333
10334    // =========================================================
10335    // CONTENT PROVIDERS
10336    // =========================================================
10337
10338    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10339        List<ProviderInfo> providers = null;
10340        try {
10341            providers = AppGlobals.getPackageManager()
10342                    .queryContentProviders(app.processName, app.uid,
10343                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10344                                    | MATCH_DEBUG_TRIAGED_MISSING)
10345                    .getList();
10346        } catch (RemoteException ex) {
10347        }
10348        if (DEBUG_MU) Slog.v(TAG_MU,
10349                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10350        int userId = app.userId;
10351        if (providers != null) {
10352            int N = providers.size();
10353            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10354            for (int i=0; i<N; i++) {
10355                // TODO: keep logic in sync with installEncryptionUnawareProviders
10356                ProviderInfo cpi =
10357                    (ProviderInfo)providers.get(i);
10358                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10359                        cpi.name, cpi.flags);
10360                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10361                    // This is a singleton provider, but a user besides the
10362                    // default user is asking to initialize a process it runs
10363                    // in...  well, no, it doesn't actually run in this process,
10364                    // it runs in the process of the default user.  Get rid of it.
10365                    providers.remove(i);
10366                    N--;
10367                    i--;
10368                    continue;
10369                }
10370
10371                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10372                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10373                if (cpr == null) {
10374                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10375                    mProviderMap.putProviderByClass(comp, cpr);
10376                }
10377                if (DEBUG_MU) Slog.v(TAG_MU,
10378                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10379                app.pubProviders.put(cpi.name, cpr);
10380                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10381                    // Don't add this if it is a platform component that is marked
10382                    // to run in multiple processes, because this is actually
10383                    // part of the framework so doesn't make sense to track as a
10384                    // separate apk in the process.
10385                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10386                            mProcessStats);
10387                }
10388                notifyPackageUse(cpi.applicationInfo.packageName,
10389                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10390            }
10391        }
10392        return providers;
10393    }
10394
10395    /**
10396     * Check if the calling UID has a possible chance at accessing the provider
10397     * at the given authority and user.
10398     */
10399    public String checkContentProviderAccess(String authority, int userId) {
10400        if (userId == UserHandle.USER_ALL) {
10401            mContext.enforceCallingOrSelfPermission(
10402                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10403            userId = UserHandle.getCallingUserId();
10404        }
10405
10406        ProviderInfo cpi = null;
10407        try {
10408            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10409                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10410                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10411                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10412                    userId);
10413        } catch (RemoteException ignored) {
10414        }
10415        if (cpi == null) {
10416            // TODO: make this an outright failure in a future platform release;
10417            // until then anonymous content notifications are unprotected
10418            //return "Failed to find provider " + authority + " for user " + userId;
10419            return null;
10420        }
10421
10422        ProcessRecord r = null;
10423        synchronized (mPidsSelfLocked) {
10424            r = mPidsSelfLocked.get(Binder.getCallingPid());
10425        }
10426        if (r == null) {
10427            return "Failed to find PID " + Binder.getCallingPid();
10428        }
10429
10430        synchronized (this) {
10431            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10432        }
10433    }
10434
10435    /**
10436     * Check if {@link ProcessRecord} has a possible chance at accessing the
10437     * given {@link ProviderInfo}. Final permission checking is always done
10438     * in {@link ContentProvider}.
10439     */
10440    private final String checkContentProviderPermissionLocked(
10441            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10442        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10443        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10444        boolean checkedGrants = false;
10445        if (checkUser) {
10446            // Looking for cross-user grants before enforcing the typical cross-users permissions
10447            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10448            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10449                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10450                    return null;
10451                }
10452                checkedGrants = true;
10453            }
10454            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10455                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10456            if (userId != tmpTargetUserId) {
10457                // When we actually went to determine the final targer user ID, this ended
10458                // up different than our initial check for the authority.  This is because
10459                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10460                // SELF.  So we need to re-check the grants again.
10461                checkedGrants = false;
10462            }
10463        }
10464        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10465                cpi.applicationInfo.uid, cpi.exported)
10466                == PackageManager.PERMISSION_GRANTED) {
10467            return null;
10468        }
10469        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10470                cpi.applicationInfo.uid, cpi.exported)
10471                == PackageManager.PERMISSION_GRANTED) {
10472            return null;
10473        }
10474
10475        PathPermission[] pps = cpi.pathPermissions;
10476        if (pps != null) {
10477            int i = pps.length;
10478            while (i > 0) {
10479                i--;
10480                PathPermission pp = pps[i];
10481                String pprperm = pp.getReadPermission();
10482                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10483                        cpi.applicationInfo.uid, cpi.exported)
10484                        == PackageManager.PERMISSION_GRANTED) {
10485                    return null;
10486                }
10487                String ppwperm = pp.getWritePermission();
10488                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10489                        cpi.applicationInfo.uid, cpi.exported)
10490                        == PackageManager.PERMISSION_GRANTED) {
10491                    return null;
10492                }
10493            }
10494        }
10495        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10496            return null;
10497        }
10498
10499        String msg;
10500        if (!cpi.exported) {
10501            msg = "Permission Denial: opening provider " + cpi.name
10502                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10503                    + ", uid=" + callingUid + ") that is not exported from uid "
10504                    + cpi.applicationInfo.uid;
10505        } else {
10506            msg = "Permission Denial: opening provider " + cpi.name
10507                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10508                    + ", uid=" + callingUid + ") requires "
10509                    + cpi.readPermission + " or " + cpi.writePermission;
10510        }
10511        Slog.w(TAG, msg);
10512        return msg;
10513    }
10514
10515    /**
10516     * Returns if the ContentProvider has granted a uri to callingUid
10517     */
10518    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10519        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10520        if (perms != null) {
10521            for (int i=perms.size()-1; i>=0; i--) {
10522                GrantUri grantUri = perms.keyAt(i);
10523                if (grantUri.sourceUserId == userId || !checkUser) {
10524                    if (matchesProvider(grantUri.uri, cpi)) {
10525                        return true;
10526                    }
10527                }
10528            }
10529        }
10530        return false;
10531    }
10532
10533    /**
10534     * Returns true if the uri authority is one of the authorities specified in the provider.
10535     */
10536    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10537        String uriAuth = uri.getAuthority();
10538        String cpiAuth = cpi.authority;
10539        if (cpiAuth.indexOf(';') == -1) {
10540            return cpiAuth.equals(uriAuth);
10541        }
10542        String[] cpiAuths = cpiAuth.split(";");
10543        int length = cpiAuths.length;
10544        for (int i = 0; i < length; i++) {
10545            if (cpiAuths[i].equals(uriAuth)) return true;
10546        }
10547        return false;
10548    }
10549
10550    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10551            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10552        if (r != null) {
10553            for (int i=0; i<r.conProviders.size(); i++) {
10554                ContentProviderConnection conn = r.conProviders.get(i);
10555                if (conn.provider == cpr) {
10556                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10557                            "Adding provider requested by "
10558                            + r.processName + " from process "
10559                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10560                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10561                    if (stable) {
10562                        conn.stableCount++;
10563                        conn.numStableIncs++;
10564                    } else {
10565                        conn.unstableCount++;
10566                        conn.numUnstableIncs++;
10567                    }
10568                    return conn;
10569                }
10570            }
10571            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10572            if (stable) {
10573                conn.stableCount = 1;
10574                conn.numStableIncs = 1;
10575            } else {
10576                conn.unstableCount = 1;
10577                conn.numUnstableIncs = 1;
10578            }
10579            cpr.connections.add(conn);
10580            r.conProviders.add(conn);
10581            startAssociationLocked(r.uid, r.processName, r.curProcState,
10582                    cpr.uid, cpr.name, cpr.info.processName);
10583            return conn;
10584        }
10585        cpr.addExternalProcessHandleLocked(externalProcessToken);
10586        return null;
10587    }
10588
10589    boolean decProviderCountLocked(ContentProviderConnection conn,
10590            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10591        if (conn != null) {
10592            cpr = conn.provider;
10593            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10594                    "Removing provider requested by "
10595                    + conn.client.processName + " from process "
10596                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10597                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10598            if (stable) {
10599                conn.stableCount--;
10600            } else {
10601                conn.unstableCount--;
10602            }
10603            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10604                cpr.connections.remove(conn);
10605                conn.client.conProviders.remove(conn);
10606                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10607                    // The client is more important than last activity -- note the time this
10608                    // is happening, so we keep the old provider process around a bit as last
10609                    // activity to avoid thrashing it.
10610                    if (cpr.proc != null) {
10611                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10612                    }
10613                }
10614                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10615                return true;
10616            }
10617            return false;
10618        }
10619        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10620        return false;
10621    }
10622
10623    private void checkTime(long startTime, String where) {
10624        long now = SystemClock.uptimeMillis();
10625        if ((now-startTime) > 50) {
10626            // If we are taking more than 50ms, log about it.
10627            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10628        }
10629    }
10630
10631    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10632            PROC_SPACE_TERM,
10633            PROC_SPACE_TERM|PROC_PARENS,
10634            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10635    };
10636
10637    private final long[] mProcessStateStatsLongs = new long[1];
10638
10639    boolean isProcessAliveLocked(ProcessRecord proc) {
10640        if (proc.procStatFile == null) {
10641            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10642        }
10643        mProcessStateStatsLongs[0] = 0;
10644        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10645                mProcessStateStatsLongs, null)) {
10646            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10647            return false;
10648        }
10649        final long state = mProcessStateStatsLongs[0];
10650        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10651                + (char)state);
10652        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10653    }
10654
10655    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10656            String name, IBinder token, boolean stable, int userId) {
10657        ContentProviderRecord cpr;
10658        ContentProviderConnection conn = null;
10659        ProviderInfo cpi = null;
10660
10661        synchronized(this) {
10662            long startTime = SystemClock.uptimeMillis();
10663
10664            ProcessRecord r = null;
10665            if (caller != null) {
10666                r = getRecordForAppLocked(caller);
10667                if (r == null) {
10668                    throw new SecurityException(
10669                            "Unable to find app for caller " + caller
10670                          + " (pid=" + Binder.getCallingPid()
10671                          + ") when getting content provider " + name);
10672                }
10673            }
10674
10675            boolean checkCrossUser = true;
10676
10677            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10678
10679            // First check if this content provider has been published...
10680            cpr = mProviderMap.getProviderByName(name, userId);
10681            // If that didn't work, check if it exists for user 0 and then
10682            // verify that it's a singleton provider before using it.
10683            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10684                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10685                if (cpr != null) {
10686                    cpi = cpr.info;
10687                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10688                            cpi.name, cpi.flags)
10689                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10690                        userId = UserHandle.USER_SYSTEM;
10691                        checkCrossUser = false;
10692                    } else {
10693                        cpr = null;
10694                        cpi = null;
10695                    }
10696                }
10697            }
10698
10699            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10700            if (providerRunning) {
10701                cpi = cpr.info;
10702                String msg;
10703                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10704                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10705                        != null) {
10706                    throw new SecurityException(msg);
10707                }
10708                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10709
10710                if (r != null && cpr.canRunHere(r)) {
10711                    // This provider has been published or is in the process
10712                    // of being published...  but it is also allowed to run
10713                    // in the caller's process, so don't make a connection
10714                    // and just let the caller instantiate its own instance.
10715                    ContentProviderHolder holder = cpr.newHolder(null);
10716                    // don't give caller the provider object, it needs
10717                    // to make its own.
10718                    holder.provider = null;
10719                    return holder;
10720                }
10721
10722                final long origId = Binder.clearCallingIdentity();
10723
10724                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10725
10726                // In this case the provider instance already exists, so we can
10727                // return it right away.
10728                conn = incProviderCountLocked(r, cpr, token, stable);
10729                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10730                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10731                        // If this is a perceptible app accessing the provider,
10732                        // make sure to count it as being accessed and thus
10733                        // back up on the LRU list.  This is good because
10734                        // content providers are often expensive to start.
10735                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10736                        updateLruProcessLocked(cpr.proc, false, null);
10737                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10738                    }
10739                }
10740
10741                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10742                final int verifiedAdj = cpr.proc.verifiedAdj;
10743                boolean success = updateOomAdjLocked(cpr.proc);
10744                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10745                // if the process has been successfully adjusted.  So to reduce races with
10746                // it, we will check whether the process still exists.  Note that this doesn't
10747                // completely get rid of races with LMK killing the process, but should make
10748                // them much smaller.
10749                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10750                    success = false;
10751                }
10752                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10753                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10754                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10755                // NOTE: there is still a race here where a signal could be
10756                // pending on the process even though we managed to update its
10757                // adj level.  Not sure what to do about this, but at least
10758                // the race is now smaller.
10759                if (!success) {
10760                    // Uh oh...  it looks like the provider's process
10761                    // has been killed on us.  We need to wait for a new
10762                    // process to be started, and make sure its death
10763                    // doesn't kill our process.
10764                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10765                            + " is crashing; detaching " + r);
10766                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10767                    checkTime(startTime, "getContentProviderImpl: before appDied");
10768                    appDiedLocked(cpr.proc);
10769                    checkTime(startTime, "getContentProviderImpl: after appDied");
10770                    if (!lastRef) {
10771                        // This wasn't the last ref our process had on
10772                        // the provider...  we have now been killed, bail.
10773                        return null;
10774                    }
10775                    providerRunning = false;
10776                    conn = null;
10777                } else {
10778                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10779                }
10780
10781                Binder.restoreCallingIdentity(origId);
10782            }
10783
10784            if (!providerRunning) {
10785                try {
10786                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10787                    cpi = AppGlobals.getPackageManager().
10788                        resolveContentProvider(name,
10789                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10790                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10791                } catch (RemoteException ex) {
10792                }
10793                if (cpi == null) {
10794                    return null;
10795                }
10796                // If the provider is a singleton AND
10797                // (it's a call within the same user || the provider is a
10798                // privileged app)
10799                // Then allow connecting to the singleton provider
10800                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10801                        cpi.name, cpi.flags)
10802                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10803                if (singleton) {
10804                    userId = UserHandle.USER_SYSTEM;
10805                }
10806                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10807                checkTime(startTime, "getContentProviderImpl: got app info for user");
10808
10809                String msg;
10810                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10811                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10812                        != null) {
10813                    throw new SecurityException(msg);
10814                }
10815                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10816
10817                if (!mProcessesReady
10818                        && !cpi.processName.equals("system")) {
10819                    // If this content provider does not run in the system
10820                    // process, and the system is not yet ready to run other
10821                    // processes, then fail fast instead of hanging.
10822                    throw new IllegalArgumentException(
10823                            "Attempt to launch content provider before system ready");
10824                }
10825
10826                // Make sure that the user who owns this provider is running.  If not,
10827                // we don't want to allow it to run.
10828                if (!mUserController.isUserRunningLocked(userId, 0)) {
10829                    Slog.w(TAG, "Unable to launch app "
10830                            + cpi.applicationInfo.packageName + "/"
10831                            + cpi.applicationInfo.uid + " for provider "
10832                            + name + ": user " + userId + " is stopped");
10833                    return null;
10834                }
10835
10836                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10837                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10838                cpr = mProviderMap.getProviderByClass(comp, userId);
10839                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10840                final boolean firstClass = cpr == null;
10841                if (firstClass) {
10842                    final long ident = Binder.clearCallingIdentity();
10843
10844                    // If permissions need a review before any of the app components can run,
10845                    // we return no provider and launch a review activity if the calling app
10846                    // is in the foreground.
10847                    if (mPermissionReviewRequired) {
10848                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10849                            return null;
10850                        }
10851                    }
10852
10853                    try {
10854                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10855                        ApplicationInfo ai =
10856                            AppGlobals.getPackageManager().
10857                                getApplicationInfo(
10858                                        cpi.applicationInfo.packageName,
10859                                        STOCK_PM_FLAGS, userId);
10860                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10861                        if (ai == null) {
10862                            Slog.w(TAG, "No package info for content provider "
10863                                    + cpi.name);
10864                            return null;
10865                        }
10866                        ai = getAppInfoForUser(ai, userId);
10867                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10868                    } catch (RemoteException ex) {
10869                        // pm is in same process, this will never happen.
10870                    } finally {
10871                        Binder.restoreCallingIdentity(ident);
10872                    }
10873                }
10874
10875                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10876
10877                if (r != null && cpr.canRunHere(r)) {
10878                    // If this is a multiprocess provider, then just return its
10879                    // info and allow the caller to instantiate it.  Only do
10880                    // this if the provider is the same user as the caller's
10881                    // process, or can run as root (so can be in any process).
10882                    return cpr.newHolder(null);
10883                }
10884
10885                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10886                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10887                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10888
10889                // This is single process, and our app is now connecting to it.
10890                // See if we are already in the process of launching this
10891                // provider.
10892                final int N = mLaunchingProviders.size();
10893                int i;
10894                for (i = 0; i < N; i++) {
10895                    if (mLaunchingProviders.get(i) == cpr) {
10896                        break;
10897                    }
10898                }
10899
10900                // If the provider is not already being launched, then get it
10901                // started.
10902                if (i >= N) {
10903                    final long origId = Binder.clearCallingIdentity();
10904
10905                    try {
10906                        // Content provider is now in use, its package can't be stopped.
10907                        try {
10908                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10909                            AppGlobals.getPackageManager().setPackageStoppedState(
10910                                    cpr.appInfo.packageName, false, userId);
10911                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10912                        } catch (RemoteException e) {
10913                        } catch (IllegalArgumentException e) {
10914                            Slog.w(TAG, "Failed trying to unstop package "
10915                                    + cpr.appInfo.packageName + ": " + e);
10916                        }
10917
10918                        // Use existing process if already started
10919                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10920                        ProcessRecord proc = getProcessRecordLocked(
10921                                cpi.processName, cpr.appInfo.uid, false);
10922                        if (proc != null && proc.thread != null && !proc.killed) {
10923                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10924                                    "Installing in existing process " + proc);
10925                            if (!proc.pubProviders.containsKey(cpi.name)) {
10926                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10927                                proc.pubProviders.put(cpi.name, cpr);
10928                                try {
10929                                    proc.thread.scheduleInstallProvider(cpi);
10930                                } catch (RemoteException e) {
10931                                }
10932                            }
10933                        } else {
10934                            checkTime(startTime, "getContentProviderImpl: before start process");
10935                            proc = startProcessLocked(cpi.processName,
10936                                    cpr.appInfo, false, 0, "content provider",
10937                                    new ComponentName(cpi.applicationInfo.packageName,
10938                                            cpi.name), false, false, false);
10939                            checkTime(startTime, "getContentProviderImpl: after start process");
10940                            if (proc == null) {
10941                                Slog.w(TAG, "Unable to launch app "
10942                                        + cpi.applicationInfo.packageName + "/"
10943                                        + cpi.applicationInfo.uid + " for provider "
10944                                        + name + ": process is bad");
10945                                return null;
10946                            }
10947                        }
10948                        cpr.launchingApp = proc;
10949                        mLaunchingProviders.add(cpr);
10950                    } finally {
10951                        Binder.restoreCallingIdentity(origId);
10952                    }
10953                }
10954
10955                checkTime(startTime, "getContentProviderImpl: updating data structures");
10956
10957                // Make sure the provider is published (the same provider class
10958                // may be published under multiple names).
10959                if (firstClass) {
10960                    mProviderMap.putProviderByClass(comp, cpr);
10961                }
10962
10963                mProviderMap.putProviderByName(name, cpr);
10964                conn = incProviderCountLocked(r, cpr, token, stable);
10965                if (conn != null) {
10966                    conn.waiting = true;
10967                }
10968            }
10969            checkTime(startTime, "getContentProviderImpl: done!");
10970        }
10971
10972        // Wait for the provider to be published...
10973        synchronized (cpr) {
10974            while (cpr.provider == null) {
10975                if (cpr.launchingApp == null) {
10976                    Slog.w(TAG, "Unable to launch app "
10977                            + cpi.applicationInfo.packageName + "/"
10978                            + cpi.applicationInfo.uid + " for provider "
10979                            + name + ": launching app became null");
10980                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10981                            UserHandle.getUserId(cpi.applicationInfo.uid),
10982                            cpi.applicationInfo.packageName,
10983                            cpi.applicationInfo.uid, name);
10984                    return null;
10985                }
10986                try {
10987                    if (DEBUG_MU) Slog.v(TAG_MU,
10988                            "Waiting to start provider " + cpr
10989                            + " launchingApp=" + cpr.launchingApp);
10990                    if (conn != null) {
10991                        conn.waiting = true;
10992                    }
10993                    cpr.wait();
10994                } catch (InterruptedException ex) {
10995                } finally {
10996                    if (conn != null) {
10997                        conn.waiting = false;
10998                    }
10999                }
11000            }
11001        }
11002        return cpr != null ? cpr.newHolder(conn) : null;
11003    }
11004
11005    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11006            ProcessRecord r, final int userId) {
11007        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11008                cpi.packageName, userId)) {
11009
11010            final boolean callerForeground = r == null || r.setSchedGroup
11011                    != ProcessList.SCHED_GROUP_BACKGROUND;
11012
11013            // Show a permission review UI only for starting from a foreground app
11014            if (!callerForeground) {
11015                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11016                        + cpi.packageName + " requires a permissions review");
11017                return false;
11018            }
11019
11020            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11021            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11022                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11023            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11024
11025            if (DEBUG_PERMISSIONS_REVIEW) {
11026                Slog.i(TAG, "u" + userId + " Launching permission review "
11027                        + "for package " + cpi.packageName);
11028            }
11029
11030            final UserHandle userHandle = new UserHandle(userId);
11031            mHandler.post(new Runnable() {
11032                @Override
11033                public void run() {
11034                    mContext.startActivityAsUser(intent, userHandle);
11035                }
11036            });
11037
11038            return false;
11039        }
11040
11041        return true;
11042    }
11043
11044    PackageManagerInternal getPackageManagerInternalLocked() {
11045        if (mPackageManagerInt == null) {
11046            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11047        }
11048        return mPackageManagerInt;
11049    }
11050
11051    @Override
11052    public final ContentProviderHolder getContentProvider(
11053            IApplicationThread caller, String name, int userId, boolean stable) {
11054        enforceNotIsolatedCaller("getContentProvider");
11055        if (caller == null) {
11056            String msg = "null IApplicationThread when getting content provider "
11057                    + name;
11058            Slog.w(TAG, msg);
11059            throw new SecurityException(msg);
11060        }
11061        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11062        // with cross-user grant.
11063        return getContentProviderImpl(caller, name, null, stable, userId);
11064    }
11065
11066    public ContentProviderHolder getContentProviderExternal(
11067            String name, int userId, IBinder token) {
11068        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11069            "Do not have permission in call getContentProviderExternal()");
11070        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11071                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11072        return getContentProviderExternalUnchecked(name, token, userId);
11073    }
11074
11075    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11076            IBinder token, int userId) {
11077        return getContentProviderImpl(null, name, token, true, userId);
11078    }
11079
11080    /**
11081     * Drop a content provider from a ProcessRecord's bookkeeping
11082     */
11083    public void removeContentProvider(IBinder connection, boolean stable) {
11084        enforceNotIsolatedCaller("removeContentProvider");
11085        long ident = Binder.clearCallingIdentity();
11086        try {
11087            synchronized (this) {
11088                ContentProviderConnection conn;
11089                try {
11090                    conn = (ContentProviderConnection)connection;
11091                } catch (ClassCastException e) {
11092                    String msg ="removeContentProvider: " + connection
11093                            + " not a ContentProviderConnection";
11094                    Slog.w(TAG, msg);
11095                    throw new IllegalArgumentException(msg);
11096                }
11097                if (conn == null) {
11098                    throw new NullPointerException("connection is null");
11099                }
11100                if (decProviderCountLocked(conn, null, null, stable)) {
11101                    updateOomAdjLocked();
11102                }
11103            }
11104        } finally {
11105            Binder.restoreCallingIdentity(ident);
11106        }
11107    }
11108
11109    public void removeContentProviderExternal(String name, IBinder token) {
11110        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11111            "Do not have permission in call removeContentProviderExternal()");
11112        int userId = UserHandle.getCallingUserId();
11113        long ident = Binder.clearCallingIdentity();
11114        try {
11115            removeContentProviderExternalUnchecked(name, token, userId);
11116        } finally {
11117            Binder.restoreCallingIdentity(ident);
11118        }
11119    }
11120
11121    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11122        synchronized (this) {
11123            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11124            if(cpr == null) {
11125                //remove from mProvidersByClass
11126                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11127                return;
11128            }
11129
11130            //update content provider record entry info
11131            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11132            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11133            if (localCpr.hasExternalProcessHandles()) {
11134                if (localCpr.removeExternalProcessHandleLocked(token)) {
11135                    updateOomAdjLocked();
11136                } else {
11137                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11138                            + " with no external reference for token: "
11139                            + token + ".");
11140                }
11141            } else {
11142                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11143                        + " with no external references.");
11144            }
11145        }
11146    }
11147
11148    public final void publishContentProviders(IApplicationThread caller,
11149            List<ContentProviderHolder> providers) {
11150        if (providers == null) {
11151            return;
11152        }
11153
11154        enforceNotIsolatedCaller("publishContentProviders");
11155        synchronized (this) {
11156            final ProcessRecord r = getRecordForAppLocked(caller);
11157            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11158            if (r == null) {
11159                throw new SecurityException(
11160                        "Unable to find app for caller " + caller
11161                      + " (pid=" + Binder.getCallingPid()
11162                      + ") when publishing content providers");
11163            }
11164
11165            final long origId = Binder.clearCallingIdentity();
11166
11167            final int N = providers.size();
11168            for (int i = 0; i < N; i++) {
11169                ContentProviderHolder src = providers.get(i);
11170                if (src == null || src.info == null || src.provider == null) {
11171                    continue;
11172                }
11173                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11174                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11175                if (dst != null) {
11176                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11177                    mProviderMap.putProviderByClass(comp, dst);
11178                    String names[] = dst.info.authority.split(";");
11179                    for (int j = 0; j < names.length; j++) {
11180                        mProviderMap.putProviderByName(names[j], dst);
11181                    }
11182
11183                    int launchingCount = mLaunchingProviders.size();
11184                    int j;
11185                    boolean wasInLaunchingProviders = false;
11186                    for (j = 0; j < launchingCount; j++) {
11187                        if (mLaunchingProviders.get(j) == dst) {
11188                            mLaunchingProviders.remove(j);
11189                            wasInLaunchingProviders = true;
11190                            j--;
11191                            launchingCount--;
11192                        }
11193                    }
11194                    if (wasInLaunchingProviders) {
11195                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11196                    }
11197                    synchronized (dst) {
11198                        dst.provider = src.provider;
11199                        dst.proc = r;
11200                        dst.notifyAll();
11201                    }
11202                    updateOomAdjLocked(r);
11203                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11204                            src.info.authority);
11205                }
11206            }
11207
11208            Binder.restoreCallingIdentity(origId);
11209        }
11210    }
11211
11212    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11213        ContentProviderConnection conn;
11214        try {
11215            conn = (ContentProviderConnection)connection;
11216        } catch (ClassCastException e) {
11217            String msg ="refContentProvider: " + connection
11218                    + " not a ContentProviderConnection";
11219            Slog.w(TAG, msg);
11220            throw new IllegalArgumentException(msg);
11221        }
11222        if (conn == null) {
11223            throw new NullPointerException("connection is null");
11224        }
11225
11226        synchronized (this) {
11227            if (stable > 0) {
11228                conn.numStableIncs += stable;
11229            }
11230            stable = conn.stableCount + stable;
11231            if (stable < 0) {
11232                throw new IllegalStateException("stableCount < 0: " + stable);
11233            }
11234
11235            if (unstable > 0) {
11236                conn.numUnstableIncs += unstable;
11237            }
11238            unstable = conn.unstableCount + unstable;
11239            if (unstable < 0) {
11240                throw new IllegalStateException("unstableCount < 0: " + unstable);
11241            }
11242
11243            if ((stable+unstable) <= 0) {
11244                throw new IllegalStateException("ref counts can't go to zero here: stable="
11245                        + stable + " unstable=" + unstable);
11246            }
11247            conn.stableCount = stable;
11248            conn.unstableCount = unstable;
11249            return !conn.dead;
11250        }
11251    }
11252
11253    public void unstableProviderDied(IBinder connection) {
11254        ContentProviderConnection conn;
11255        try {
11256            conn = (ContentProviderConnection)connection;
11257        } catch (ClassCastException e) {
11258            String msg ="refContentProvider: " + connection
11259                    + " not a ContentProviderConnection";
11260            Slog.w(TAG, msg);
11261            throw new IllegalArgumentException(msg);
11262        }
11263        if (conn == null) {
11264            throw new NullPointerException("connection is null");
11265        }
11266
11267        // Safely retrieve the content provider associated with the connection.
11268        IContentProvider provider;
11269        synchronized (this) {
11270            provider = conn.provider.provider;
11271        }
11272
11273        if (provider == null) {
11274            // Um, yeah, we're way ahead of you.
11275            return;
11276        }
11277
11278        // Make sure the caller is being honest with us.
11279        if (provider.asBinder().pingBinder()) {
11280            // Er, no, still looks good to us.
11281            synchronized (this) {
11282                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11283                        + " says " + conn + " died, but we don't agree");
11284                return;
11285            }
11286        }
11287
11288        // Well look at that!  It's dead!
11289        synchronized (this) {
11290            if (conn.provider.provider != provider) {
11291                // But something changed...  good enough.
11292                return;
11293            }
11294
11295            ProcessRecord proc = conn.provider.proc;
11296            if (proc == null || proc.thread == null) {
11297                // Seems like the process is already cleaned up.
11298                return;
11299            }
11300
11301            // As far as we're concerned, this is just like receiving a
11302            // death notification...  just a bit prematurely.
11303            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11304                    + ") early provider death");
11305            final long ident = Binder.clearCallingIdentity();
11306            try {
11307                appDiedLocked(proc);
11308            } finally {
11309                Binder.restoreCallingIdentity(ident);
11310            }
11311        }
11312    }
11313
11314    @Override
11315    public void appNotRespondingViaProvider(IBinder connection) {
11316        enforceCallingPermission(
11317                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11318
11319        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11320        if (conn == null) {
11321            Slog.w(TAG, "ContentProviderConnection is null");
11322            return;
11323        }
11324
11325        final ProcessRecord host = conn.provider.proc;
11326        if (host == null) {
11327            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11328            return;
11329        }
11330
11331        mHandler.post(new Runnable() {
11332            @Override
11333            public void run() {
11334                mAppErrors.appNotResponding(host, null, null, false,
11335                        "ContentProvider not responding");
11336            }
11337        });
11338    }
11339
11340    public final void installSystemProviders() {
11341        List<ProviderInfo> providers;
11342        synchronized (this) {
11343            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11344            providers = generateApplicationProvidersLocked(app);
11345            if (providers != null) {
11346                for (int i=providers.size()-1; i>=0; i--) {
11347                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11348                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11349                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11350                                + ": not system .apk");
11351                        providers.remove(i);
11352                    }
11353                }
11354            }
11355        }
11356        if (providers != null) {
11357            mSystemThread.installSystemProviders(providers);
11358        }
11359
11360        mCoreSettingsObserver = new CoreSettingsObserver(this);
11361        mFontScaleSettingObserver = new FontScaleSettingObserver();
11362
11363        //mUsageStatsService.monitorPackages();
11364    }
11365
11366    private void startPersistentApps(int matchFlags) {
11367        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11368
11369        synchronized (this) {
11370            try {
11371                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11372                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11373                for (ApplicationInfo app : apps) {
11374                    if (!"android".equals(app.packageName)) {
11375                        addAppLocked(app, false, null /* ABI override */);
11376                    }
11377                }
11378            } catch (RemoteException ex) {
11379            }
11380        }
11381    }
11382
11383    /**
11384     * When a user is unlocked, we need to install encryption-unaware providers
11385     * belonging to any running apps.
11386     */
11387    private void installEncryptionUnawareProviders(int userId) {
11388        // We're only interested in providers that are encryption unaware, and
11389        // we don't care about uninstalled apps, since there's no way they're
11390        // running at this point.
11391        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11392
11393        synchronized (this) {
11394            final int NP = mProcessNames.getMap().size();
11395            for (int ip = 0; ip < NP; ip++) {
11396                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11397                final int NA = apps.size();
11398                for (int ia = 0; ia < NA; ia++) {
11399                    final ProcessRecord app = apps.valueAt(ia);
11400                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11401
11402                    final int NG = app.pkgList.size();
11403                    for (int ig = 0; ig < NG; ig++) {
11404                        try {
11405                            final String pkgName = app.pkgList.keyAt(ig);
11406                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11407                                    .getPackageInfo(pkgName, matchFlags, userId);
11408                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11409                                for (ProviderInfo pi : pkgInfo.providers) {
11410                                    // TODO: keep in sync with generateApplicationProvidersLocked
11411                                    final boolean processMatch = Objects.equals(pi.processName,
11412                                            app.processName) || pi.multiprocess;
11413                                    final boolean userMatch = isSingleton(pi.processName,
11414                                            pi.applicationInfo, pi.name, pi.flags)
11415                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11416                                    if (processMatch && userMatch) {
11417                                        Log.v(TAG, "Installing " + pi);
11418                                        app.thread.scheduleInstallProvider(pi);
11419                                    } else {
11420                                        Log.v(TAG, "Skipping " + pi);
11421                                    }
11422                                }
11423                            }
11424                        } catch (RemoteException ignored) {
11425                        }
11426                    }
11427                }
11428            }
11429        }
11430    }
11431
11432    /**
11433     * Allows apps to retrieve the MIME type of a URI.
11434     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11435     * users, then it does not need permission to access the ContentProvider.
11436     * Either, it needs cross-user uri grants.
11437     *
11438     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11439     *
11440     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11441     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11442     */
11443    public String getProviderMimeType(Uri uri, int userId) {
11444        enforceNotIsolatedCaller("getProviderMimeType");
11445        final String name = uri.getAuthority();
11446        int callingUid = Binder.getCallingUid();
11447        int callingPid = Binder.getCallingPid();
11448        long ident = 0;
11449        boolean clearedIdentity = false;
11450        synchronized (this) {
11451            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11452        }
11453        if (canClearIdentity(callingPid, callingUid, userId)) {
11454            clearedIdentity = true;
11455            ident = Binder.clearCallingIdentity();
11456        }
11457        ContentProviderHolder holder = null;
11458        try {
11459            holder = getContentProviderExternalUnchecked(name, null, userId);
11460            if (holder != null) {
11461                return holder.provider.getType(uri);
11462            }
11463        } catch (RemoteException e) {
11464            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11465            return null;
11466        } catch (Exception e) {
11467            Log.w(TAG, "Exception while determining type of " + uri, e);
11468            return null;
11469        } finally {
11470            // We need to clear the identity to call removeContentProviderExternalUnchecked
11471            if (!clearedIdentity) {
11472                ident = Binder.clearCallingIdentity();
11473            }
11474            try {
11475                if (holder != null) {
11476                    removeContentProviderExternalUnchecked(name, null, userId);
11477                }
11478            } finally {
11479                Binder.restoreCallingIdentity(ident);
11480            }
11481        }
11482
11483        return null;
11484    }
11485
11486    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11487        if (UserHandle.getUserId(callingUid) == userId) {
11488            return true;
11489        }
11490        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11491                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11492                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11493                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11494                return true;
11495        }
11496        return false;
11497    }
11498
11499    // =========================================================
11500    // GLOBAL MANAGEMENT
11501    // =========================================================
11502
11503    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11504            boolean isolated, int isolatedUid) {
11505        String proc = customProcess != null ? customProcess : info.processName;
11506        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11507        final int userId = UserHandle.getUserId(info.uid);
11508        int uid = info.uid;
11509        if (isolated) {
11510            if (isolatedUid == 0) {
11511                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11512                while (true) {
11513                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11514                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11515                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11516                    }
11517                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11518                    mNextIsolatedProcessUid++;
11519                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11520                        // No process for this uid, use it.
11521                        break;
11522                    }
11523                    stepsLeft--;
11524                    if (stepsLeft <= 0) {
11525                        return null;
11526                    }
11527                }
11528            } else {
11529                // Special case for startIsolatedProcess (internal only), where
11530                // the uid of the isolated process is specified by the caller.
11531                uid = isolatedUid;
11532            }
11533
11534            // Register the isolated UID with this application so BatteryStats knows to
11535            // attribute resource usage to the application.
11536            //
11537            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11538            // about the process state of the isolated UID *before* it is registered with the
11539            // owning application.
11540            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11541        }
11542        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11543        if (!mBooted && !mBooting
11544                && userId == UserHandle.USER_SYSTEM
11545                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11546            r.persistent = true;
11547            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11548        }
11549        addProcessNameLocked(r);
11550        return r;
11551    }
11552
11553    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11554            String abiOverride) {
11555        ProcessRecord app;
11556        if (!isolated) {
11557            app = getProcessRecordLocked(info.processName, info.uid, true);
11558        } else {
11559            app = null;
11560        }
11561
11562        if (app == null) {
11563            app = newProcessRecordLocked(info, null, isolated, 0);
11564            updateLruProcessLocked(app, false, null);
11565            updateOomAdjLocked();
11566        }
11567
11568        // This package really, really can not be stopped.
11569        try {
11570            AppGlobals.getPackageManager().setPackageStoppedState(
11571                    info.packageName, false, UserHandle.getUserId(app.uid));
11572        } catch (RemoteException e) {
11573        } catch (IllegalArgumentException e) {
11574            Slog.w(TAG, "Failed trying to unstop package "
11575                    + info.packageName + ": " + e);
11576        }
11577
11578        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11579            app.persistent = true;
11580            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11581        }
11582        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11583            mPersistentStartingProcesses.add(app);
11584            startProcessLocked(app, "added application", app.processName, abiOverride,
11585                    null /* entryPoint */, null /* entryPointArgs */);
11586        }
11587
11588        return app;
11589    }
11590
11591    public void unhandledBack() {
11592        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11593                "unhandledBack()");
11594
11595        synchronized(this) {
11596            final long origId = Binder.clearCallingIdentity();
11597            try {
11598                getFocusedStack().unhandledBackLocked();
11599            } finally {
11600                Binder.restoreCallingIdentity(origId);
11601            }
11602        }
11603    }
11604
11605    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11606        enforceNotIsolatedCaller("openContentUri");
11607        final int userId = UserHandle.getCallingUserId();
11608        final Uri uri = Uri.parse(uriString);
11609        String name = uri.getAuthority();
11610        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11611        ParcelFileDescriptor pfd = null;
11612        if (cph != null) {
11613            // We record the binder invoker's uid in thread-local storage before
11614            // going to the content provider to open the file.  Later, in the code
11615            // that handles all permissions checks, we look for this uid and use
11616            // that rather than the Activity Manager's own uid.  The effect is that
11617            // we do the check against the caller's permissions even though it looks
11618            // to the content provider like the Activity Manager itself is making
11619            // the request.
11620            Binder token = new Binder();
11621            sCallerIdentity.set(new Identity(
11622                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11623            try {
11624                pfd = cph.provider.openFile(null, uri, "r", null, token);
11625            } catch (FileNotFoundException e) {
11626                // do nothing; pfd will be returned null
11627            } finally {
11628                // Ensure that whatever happens, we clean up the identity state
11629                sCallerIdentity.remove();
11630                // Ensure we're done with the provider.
11631                removeContentProviderExternalUnchecked(name, null, userId);
11632            }
11633        } else {
11634            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11635        }
11636        return pfd;
11637    }
11638
11639    // Actually is sleeping or shutting down or whatever else in the future
11640    // is an inactive state.
11641    boolean isSleepingOrShuttingDownLocked() {
11642        return isSleepingLocked() || mShuttingDown;
11643    }
11644
11645    boolean isShuttingDownLocked() {
11646        return mShuttingDown;
11647    }
11648
11649    boolean isSleepingLocked() {
11650        return mSleeping;
11651    }
11652
11653    void onWakefulnessChanged(int wakefulness) {
11654        synchronized(this) {
11655            mWakefulness = wakefulness;
11656            updateSleepIfNeededLocked();
11657        }
11658    }
11659
11660    void finishRunningVoiceLocked() {
11661        if (mRunningVoice != null) {
11662            mRunningVoice = null;
11663            mVoiceWakeLock.release();
11664            updateSleepIfNeededLocked();
11665        }
11666    }
11667
11668    void startTimeTrackingFocusedActivityLocked() {
11669        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11670        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11671            mCurAppTimeTracker.start(resumedActivity.packageName);
11672        }
11673    }
11674
11675    void updateSleepIfNeededLocked() {
11676        if (mSleeping && !shouldSleepLocked()) {
11677            mSleeping = false;
11678            startTimeTrackingFocusedActivityLocked();
11679            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11680            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11681            sendNotifyVrManagerOfSleepState(false);
11682            updateOomAdjLocked();
11683        } else if (!mSleeping && shouldSleepLocked()) {
11684            mSleeping = true;
11685            if (mCurAppTimeTracker != null) {
11686                mCurAppTimeTracker.stop();
11687            }
11688            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11689            mStackSupervisor.goingToSleepLocked();
11690            sendNotifyVrManagerOfSleepState(true);
11691            updateOomAdjLocked();
11692
11693            // Initialize the wake times of all processes.
11694            checkExcessivePowerUsageLocked(false);
11695            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11696            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11697            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11698        }
11699    }
11700
11701    private boolean shouldSleepLocked() {
11702        // Resume applications while running a voice interactor.
11703        if (mRunningVoice != null) {
11704            return false;
11705        }
11706
11707        // TODO: Transform the lock screen state into a sleep token instead.
11708        switch (mWakefulness) {
11709            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11710            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11711            case PowerManagerInternal.WAKEFULNESS_DOZING:
11712                // Pause applications whenever the lock screen is shown or any sleep
11713                // tokens have been acquired.
11714                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
11715            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11716            default:
11717                // If we're asleep then pause applications unconditionally.
11718                return true;
11719        }
11720    }
11721
11722    /** Pokes the task persister. */
11723    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11724        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11725    }
11726
11727    /** Notifies all listeners when the pinned stack animation ends. */
11728    @Override
11729    public void notifyPinnedStackAnimationEnded() {
11730        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11731    }
11732
11733    @Override
11734    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11735        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11736    }
11737
11738    @Override
11739    public boolean shutdown(int timeout) {
11740        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11741                != PackageManager.PERMISSION_GRANTED) {
11742            throw new SecurityException("Requires permission "
11743                    + android.Manifest.permission.SHUTDOWN);
11744        }
11745
11746        boolean timedout = false;
11747
11748        synchronized(this) {
11749            mShuttingDown = true;
11750            updateEventDispatchingLocked();
11751            timedout = mStackSupervisor.shutdownLocked(timeout);
11752        }
11753
11754        mAppOpsService.shutdown();
11755        if (mUsageStatsService != null) {
11756            mUsageStatsService.prepareShutdown();
11757        }
11758        mBatteryStatsService.shutdown();
11759        synchronized (this) {
11760            mProcessStats.shutdownLocked();
11761            notifyTaskPersisterLocked(null, true);
11762        }
11763
11764        return timedout;
11765    }
11766
11767    public final void activitySlept(IBinder token) {
11768        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11769
11770        final long origId = Binder.clearCallingIdentity();
11771
11772        synchronized (this) {
11773            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11774            if (r != null) {
11775                mStackSupervisor.activitySleptLocked(r);
11776            }
11777        }
11778
11779        Binder.restoreCallingIdentity(origId);
11780    }
11781
11782    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11783        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11784        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11785        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11786            boolean wasRunningVoice = mRunningVoice != null;
11787            mRunningVoice = session;
11788            if (!wasRunningVoice) {
11789                mVoiceWakeLock.acquire();
11790                updateSleepIfNeededLocked();
11791            }
11792        }
11793    }
11794
11795    private void updateEventDispatchingLocked() {
11796        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11797    }
11798
11799    @Override
11800    public void setLockScreenShown(boolean showing) {
11801        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11802                != PackageManager.PERMISSION_GRANTED) {
11803            throw new SecurityException("Requires permission "
11804                    + android.Manifest.permission.DEVICE_POWER);
11805        }
11806
11807        synchronized(this) {
11808            long ident = Binder.clearCallingIdentity();
11809            try {
11810                mKeyguardController.setKeyguardShown(showing);
11811            } finally {
11812                Binder.restoreCallingIdentity(ident);
11813            }
11814        }
11815    }
11816
11817    @Override
11818    public void notifyLockedProfile(@UserIdInt int userId) {
11819        try {
11820            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11821                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11822            }
11823        } catch (RemoteException ex) {
11824            throw new SecurityException("Fail to check is caller a privileged app", ex);
11825        }
11826
11827        synchronized (this) {
11828            if (mStackSupervisor.isUserLockedProfile(userId)) {
11829                final long ident = Binder.clearCallingIdentity();
11830                try {
11831                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11832                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11833                        // If there is no device lock, we will show the profile's credential page.
11834                        mActivityStarter.showConfirmDeviceCredential(userId);
11835                    } else {
11836                        // Showing launcher to avoid user entering credential twice.
11837                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11838                    }
11839                } finally {
11840                    Binder.restoreCallingIdentity(ident);
11841                }
11842            }
11843        }
11844    }
11845
11846    @Override
11847    public void startConfirmDeviceCredentialIntent(Intent intent) {
11848        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11849        synchronized (this) {
11850            final long ident = Binder.clearCallingIdentity();
11851            try {
11852                mActivityStarter.startConfirmCredentialIntent(intent);
11853            } finally {
11854                Binder.restoreCallingIdentity(ident);
11855            }
11856        }
11857    }
11858
11859    @Override
11860    public void stopAppSwitches() {
11861        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11862                != PackageManager.PERMISSION_GRANTED) {
11863            throw new SecurityException("viewquires permission "
11864                    + android.Manifest.permission.STOP_APP_SWITCHES);
11865        }
11866
11867        synchronized(this) {
11868            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11869                    + APP_SWITCH_DELAY_TIME;
11870            mDidAppSwitch = false;
11871            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11872            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11873            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11874        }
11875    }
11876
11877    public void resumeAppSwitches() {
11878        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11879                != PackageManager.PERMISSION_GRANTED) {
11880            throw new SecurityException("Requires permission "
11881                    + android.Manifest.permission.STOP_APP_SWITCHES);
11882        }
11883
11884        synchronized(this) {
11885            // Note that we don't execute any pending app switches... we will
11886            // let those wait until either the timeout, or the next start
11887            // activity request.
11888            mAppSwitchesAllowedTime = 0;
11889        }
11890    }
11891
11892    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11893            int callingPid, int callingUid, String name) {
11894        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11895            return true;
11896        }
11897
11898        int perm = checkComponentPermission(
11899                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11900                sourceUid, -1, true);
11901        if (perm == PackageManager.PERMISSION_GRANTED) {
11902            return true;
11903        }
11904
11905        // If the actual IPC caller is different from the logical source, then
11906        // also see if they are allowed to control app switches.
11907        if (callingUid != -1 && callingUid != sourceUid) {
11908            perm = checkComponentPermission(
11909                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11910                    callingUid, -1, true);
11911            if (perm == PackageManager.PERMISSION_GRANTED) {
11912                return true;
11913            }
11914        }
11915
11916        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11917        return false;
11918    }
11919
11920    public void setDebugApp(String packageName, boolean waitForDebugger,
11921            boolean persistent) {
11922        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11923                "setDebugApp()");
11924
11925        long ident = Binder.clearCallingIdentity();
11926        try {
11927            // Note that this is not really thread safe if there are multiple
11928            // callers into it at the same time, but that's not a situation we
11929            // care about.
11930            if (persistent) {
11931                final ContentResolver resolver = mContext.getContentResolver();
11932                Settings.Global.putString(
11933                    resolver, Settings.Global.DEBUG_APP,
11934                    packageName);
11935                Settings.Global.putInt(
11936                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11937                    waitForDebugger ? 1 : 0);
11938            }
11939
11940            synchronized (this) {
11941                if (!persistent) {
11942                    mOrigDebugApp = mDebugApp;
11943                    mOrigWaitForDebugger = mWaitForDebugger;
11944                }
11945                mDebugApp = packageName;
11946                mWaitForDebugger = waitForDebugger;
11947                mDebugTransient = !persistent;
11948                if (packageName != null) {
11949                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11950                            false, UserHandle.USER_ALL, "set debug app");
11951                }
11952            }
11953        } finally {
11954            Binder.restoreCallingIdentity(ident);
11955        }
11956    }
11957
11958    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11959        synchronized (this) {
11960            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11961            if (!isDebuggable) {
11962                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11963                    throw new SecurityException("Process not debuggable: " + app.packageName);
11964                }
11965            }
11966
11967            mTrackAllocationApp = processName;
11968        }
11969    }
11970
11971    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11972        synchronized (this) {
11973            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11974            if (!isDebuggable) {
11975                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11976                    throw new SecurityException("Process not debuggable: " + app.packageName);
11977                }
11978            }
11979            mProfileApp = processName;
11980            mProfileFile = profilerInfo.profileFile;
11981            if (mProfileFd != null) {
11982                try {
11983                    mProfileFd.close();
11984                } catch (IOException e) {
11985                }
11986                mProfileFd = null;
11987            }
11988            mProfileFd = profilerInfo.profileFd;
11989            mSamplingInterval = profilerInfo.samplingInterval;
11990            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11991            mProfileType = 0;
11992        }
11993    }
11994
11995    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11996        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11997        if (!isDebuggable) {
11998            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11999                throw new SecurityException("Process not debuggable: " + app.packageName);
12000            }
12001        }
12002        mNativeDebuggingApp = processName;
12003    }
12004
12005    @Override
12006    public void setAlwaysFinish(boolean enabled) {
12007        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12008                "setAlwaysFinish()");
12009
12010        long ident = Binder.clearCallingIdentity();
12011        try {
12012            Settings.Global.putInt(
12013                    mContext.getContentResolver(),
12014                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12015
12016            synchronized (this) {
12017                mAlwaysFinishActivities = enabled;
12018            }
12019        } finally {
12020            Binder.restoreCallingIdentity(ident);
12021        }
12022    }
12023
12024    @Override
12025    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12026        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12027                "setActivityController()");
12028        synchronized (this) {
12029            mController = controller;
12030            mControllerIsAMonkey = imAMonkey;
12031            Watchdog.getInstance().setActivityController(controller);
12032        }
12033    }
12034
12035    @Override
12036    public void setUserIsMonkey(boolean userIsMonkey) {
12037        synchronized (this) {
12038            synchronized (mPidsSelfLocked) {
12039                final int callingPid = Binder.getCallingPid();
12040                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12041                if (precessRecord == null) {
12042                    throw new SecurityException("Unknown process: " + callingPid);
12043                }
12044                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12045                    throw new SecurityException("Only an instrumentation process "
12046                            + "with a UiAutomation can call setUserIsMonkey");
12047                }
12048            }
12049            mUserIsMonkey = userIsMonkey;
12050        }
12051    }
12052
12053    @Override
12054    public boolean isUserAMonkey() {
12055        synchronized (this) {
12056            // If there is a controller also implies the user is a monkey.
12057            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12058        }
12059    }
12060
12061    /**
12062     * @deprecated This method is only used by a few internal components and it will soon be
12063     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12064     * No new code should be calling it.
12065     */
12066    @Deprecated
12067    public void requestBugReport(int bugreportType) {
12068        String extraOptions = null;
12069        switch (bugreportType) {
12070            case ActivityManager.BUGREPORT_OPTION_FULL:
12071                // Default options.
12072                break;
12073            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12074                extraOptions = "bugreportplus";
12075                break;
12076            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12077                extraOptions = "bugreportremote";
12078                break;
12079            case ActivityManager.BUGREPORT_OPTION_WEAR:
12080                extraOptions = "bugreportwear";
12081                break;
12082            default:
12083                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12084                        + bugreportType);
12085        }
12086        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12087        if (extraOptions != null) {
12088            SystemProperties.set("dumpstate.options", extraOptions);
12089        }
12090        SystemProperties.set("ctl.start", "bugreport");
12091    }
12092
12093    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12094        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12095    }
12096
12097    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12098        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12099            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12100        }
12101        return KEY_DISPATCHING_TIMEOUT;
12102    }
12103
12104    @Override
12105    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12106        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12107                != PackageManager.PERMISSION_GRANTED) {
12108            throw new SecurityException("Requires permission "
12109                    + android.Manifest.permission.FILTER_EVENTS);
12110        }
12111        ProcessRecord proc;
12112        long timeout;
12113        synchronized (this) {
12114            synchronized (mPidsSelfLocked) {
12115                proc = mPidsSelfLocked.get(pid);
12116            }
12117            timeout = getInputDispatchingTimeoutLocked(proc);
12118        }
12119
12120        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12121            return -1;
12122        }
12123
12124        return timeout;
12125    }
12126
12127    /**
12128     * Handle input dispatching timeouts.
12129     * Returns whether input dispatching should be aborted or not.
12130     */
12131    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12132            final ActivityRecord activity, final ActivityRecord parent,
12133            final boolean aboveSystem, String reason) {
12134        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12135                != PackageManager.PERMISSION_GRANTED) {
12136            throw new SecurityException("Requires permission "
12137                    + android.Manifest.permission.FILTER_EVENTS);
12138        }
12139
12140        final String annotation;
12141        if (reason == null) {
12142            annotation = "Input dispatching timed out";
12143        } else {
12144            annotation = "Input dispatching timed out (" + reason + ")";
12145        }
12146
12147        if (proc != null) {
12148            synchronized (this) {
12149                if (proc.debugging) {
12150                    return false;
12151                }
12152
12153                if (mDidDexOpt) {
12154                    // Give more time since we were dexopting.
12155                    mDidDexOpt = false;
12156                    return false;
12157                }
12158
12159                if (proc.instrumentationClass != null) {
12160                    Bundle info = new Bundle();
12161                    info.putString("shortMsg", "keyDispatchingTimedOut");
12162                    info.putString("longMsg", annotation);
12163                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12164                    return true;
12165                }
12166            }
12167            mHandler.post(new Runnable() {
12168                @Override
12169                public void run() {
12170                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12171                }
12172            });
12173        }
12174
12175        return true;
12176    }
12177
12178    @Override
12179    public Bundle getAssistContextExtras(int requestType) {
12180        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12181                null, null, true /* focused */, true /* newSessionId */,
12182                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12183        if (pae == null) {
12184            return null;
12185        }
12186        synchronized (pae) {
12187            while (!pae.haveResult) {
12188                try {
12189                    pae.wait();
12190                } catch (InterruptedException e) {
12191                }
12192            }
12193        }
12194        synchronized (this) {
12195            buildAssistBundleLocked(pae, pae.result);
12196            mPendingAssistExtras.remove(pae);
12197            mUiHandler.removeCallbacks(pae);
12198        }
12199        return pae.extras;
12200    }
12201
12202    @Override
12203    public boolean isAssistDataAllowedOnCurrentActivity() {
12204        int userId;
12205        synchronized (this) {
12206            userId = mUserController.getCurrentUserIdLocked();
12207            ActivityRecord activity = getFocusedStack().topActivity();
12208            if (activity == null) {
12209                return false;
12210            }
12211            userId = activity.userId;
12212        }
12213        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12214                Context.DEVICE_POLICY_SERVICE);
12215        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12216    }
12217
12218    @Override
12219    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12220        long ident = Binder.clearCallingIdentity();
12221        try {
12222            synchronized (this) {
12223                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12224                ActivityRecord top = getFocusedStack().topActivity();
12225                if (top != caller) {
12226                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12227                            + " is not current top " + top);
12228                    return false;
12229                }
12230                if (!top.nowVisible) {
12231                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12232                            + " is not visible");
12233                    return false;
12234                }
12235            }
12236            AssistUtils utils = new AssistUtils(mContext);
12237            return utils.showSessionForActiveService(args,
12238                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12239        } finally {
12240            Binder.restoreCallingIdentity(ident);
12241        }
12242    }
12243
12244    @Override
12245    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12246            Bundle receiverExtras,
12247            IBinder activityToken, boolean focused, boolean newSessionId) {
12248        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12249                activityToken, focused, newSessionId,
12250                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0)
12251                != null;
12252    }
12253
12254    @Override
12255    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
12256            IBinder activityToken, int flags) {
12257        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_FULL, null, null, receiver,
12258                receiverExtras, activityToken, true, true,
12259                UserHandle.getCallingUserId(), null, PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT,
12260                flags) != null;
12261    }
12262
12263    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12264            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12265            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
12266            int flags) {
12267        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12268                "enqueueAssistContext()");
12269        synchronized (this) {
12270            ActivityRecord activity = getFocusedStack().topActivity();
12271            if (activity == null) {
12272                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12273                return null;
12274            }
12275            if (activity.app == null || activity.app.thread == null) {
12276                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12277                return null;
12278            }
12279            if (focused) {
12280                if (activityToken != null) {
12281                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12282                    if (activity != caller) {
12283                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12284                                + " is not current top " + activity);
12285                        return null;
12286                    }
12287                }
12288            } else {
12289                activity = ActivityRecord.forTokenLocked(activityToken);
12290                if (activity == null) {
12291                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12292                            + " couldn't be found");
12293                    return null;
12294                }
12295            }
12296
12297            PendingAssistExtras pae;
12298            Bundle extras = new Bundle();
12299            if (args != null) {
12300                extras.putAll(args);
12301            }
12302            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12303            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12304            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12305                    flags, userHandle);
12306            // Increment the sessionId if necessary
12307            if (newSessionId) {
12308                mViSessionId++;
12309            }
12310            try {
12311                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12312                        requestType, mViSessionId, flags);
12313                mPendingAssistExtras.add(pae);
12314                mUiHandler.postDelayed(pae, timeout);
12315            } catch (RemoteException e) {
12316                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12317                return null;
12318            }
12319            return pae;
12320        }
12321    }
12322
12323    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12324        IResultReceiver receiver;
12325        synchronized (this) {
12326            mPendingAssistExtras.remove(pae);
12327            receiver = pae.receiver;
12328        }
12329        if (receiver != null) {
12330            // Caller wants result sent back to them.
12331            Bundle sendBundle = new Bundle();
12332            // At least return the receiver extras
12333            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12334                    pae.receiverExtras);
12335            try {
12336                pae.receiver.send(0, sendBundle);
12337            } catch (RemoteException e) {
12338            }
12339        }
12340    }
12341
12342    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12343        if (result != null) {
12344            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12345        }
12346        if (pae.hint != null) {
12347            pae.extras.putBoolean(pae.hint, true);
12348        }
12349    }
12350
12351    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12352            AssistContent content, Uri referrer) {
12353        PendingAssistExtras pae = (PendingAssistExtras)token;
12354        synchronized (pae) {
12355            pae.result = extras;
12356            pae.structure = structure;
12357            pae.content = content;
12358            if (referrer != null) {
12359                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12360            }
12361            pae.haveResult = true;
12362            pae.notifyAll();
12363            if (pae.intent == null && pae.receiver == null) {
12364                // Caller is just waiting for the result.
12365                return;
12366            }
12367        }
12368
12369        // We are now ready to launch the assist activity.
12370        IResultReceiver sendReceiver = null;
12371        Bundle sendBundle = null;
12372        synchronized (this) {
12373            buildAssistBundleLocked(pae, extras);
12374            boolean exists = mPendingAssistExtras.remove(pae);
12375            mUiHandler.removeCallbacks(pae);
12376            if (!exists) {
12377                // Timed out.
12378                return;
12379            }
12380            if ((sendReceiver=pae.receiver) != null) {
12381                // Caller wants result sent back to them.
12382                sendBundle = new Bundle();
12383                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12384                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12385                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12386                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12387                        pae.receiverExtras);
12388                if (pae.flags > 0) {
12389                    sendBundle.putInt(VoiceInteractionSession.KEY_FLAGS, pae.flags);
12390                }
12391                IBinder autoFillCallback =
12392                        extras.getBinder(AutoFillService.KEY_CALLBACK);
12393                if (autoFillCallback != null) {
12394                    sendBundle.putBinder(AutoFillService.KEY_CALLBACK,
12395                            autoFillCallback);
12396                }
12397            }
12398        }
12399        if (sendReceiver != null) {
12400            try {
12401                sendReceiver.send(0, sendBundle);
12402            } catch (RemoteException e) {
12403            }
12404            return;
12405        }
12406
12407        long ident = Binder.clearCallingIdentity();
12408        try {
12409            pae.intent.replaceExtras(pae.extras);
12410            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12411                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12412                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12413            closeSystemDialogs("assist");
12414            try {
12415                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12416            } catch (ActivityNotFoundException e) {
12417                Slog.w(TAG, "No activity to handle assist action.", e);
12418            }
12419        } finally {
12420            Binder.restoreCallingIdentity(ident);
12421        }
12422    }
12423
12424    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12425            Bundle args) {
12426        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12427                true /* focused */, true /* newSessionId */,
12428                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
12429    }
12430
12431    public void registerProcessObserver(IProcessObserver observer) {
12432        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12433                "registerProcessObserver()");
12434        synchronized (this) {
12435            mProcessObservers.register(observer);
12436        }
12437    }
12438
12439    @Override
12440    public void unregisterProcessObserver(IProcessObserver observer) {
12441        synchronized (this) {
12442            mProcessObservers.unregister(observer);
12443        }
12444    }
12445
12446    @Override
12447    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12448            String callingPackage) {
12449        if (!hasUsageStatsPermission(callingPackage)) {
12450            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12451                    "registerUidObserver");
12452        }
12453        synchronized (this) {
12454            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12455                    callingPackage, which, cutpoint));
12456        }
12457    }
12458
12459    @Override
12460    public void unregisterUidObserver(IUidObserver observer) {
12461        synchronized (this) {
12462            mUidObservers.unregister(observer);
12463        }
12464    }
12465
12466    @Override
12467    public boolean convertFromTranslucent(IBinder token) {
12468        final long origId = Binder.clearCallingIdentity();
12469        try {
12470            synchronized (this) {
12471                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12472                if (r == null) {
12473                    return false;
12474                }
12475                final boolean translucentChanged = r.changeWindowTranslucency(true);
12476                if (translucentChanged) {
12477                    r.getStack().releaseBackgroundResources(r);
12478                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12479                }
12480                mWindowManager.setAppFullscreen(token, true);
12481                return translucentChanged;
12482            }
12483        } finally {
12484            Binder.restoreCallingIdentity(origId);
12485        }
12486    }
12487
12488    @Override
12489    public boolean convertToTranslucent(IBinder token, Bundle options) {
12490        final long origId = Binder.clearCallingIdentity();
12491        try {
12492            synchronized (this) {
12493                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12494                if (r == null) {
12495                    return false;
12496                }
12497                int index = r.task.mActivities.lastIndexOf(r);
12498                if (index > 0) {
12499                    ActivityRecord under = r.task.mActivities.get(index - 1);
12500                    under.returningOptions = ActivityOptions.fromBundle(options);
12501                }
12502                final boolean translucentChanged = r.changeWindowTranslucency(false);
12503                if (translucentChanged) {
12504                    r.getStack().convertActivityToTranslucent(r);
12505                }
12506                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12507                mWindowManager.setAppFullscreen(token, false);
12508                return translucentChanged;
12509            }
12510        } finally {
12511            Binder.restoreCallingIdentity(origId);
12512        }
12513    }
12514
12515    @Override
12516    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12517        final long origId = Binder.clearCallingIdentity();
12518        try {
12519            synchronized (this) {
12520                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12521                if (r != null) {
12522                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12523                }
12524            }
12525            return false;
12526        } finally {
12527            Binder.restoreCallingIdentity(origId);
12528        }
12529    }
12530
12531    @Override
12532    public boolean isBackgroundVisibleBehind(IBinder token) {
12533        final long origId = Binder.clearCallingIdentity();
12534        try {
12535            synchronized (this) {
12536                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12537                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12538                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12539                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12540                return visible;
12541            }
12542        } finally {
12543            Binder.restoreCallingIdentity(origId);
12544        }
12545    }
12546
12547    @Override
12548    public Bundle getActivityOptions(IBinder token) {
12549        final long origId = Binder.clearCallingIdentity();
12550        try {
12551            synchronized (this) {
12552                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12553                if (r != null) {
12554                    final ActivityOptions activityOptions = r.pendingOptions;
12555                    r.pendingOptions = null;
12556                    return activityOptions == null ? null : activityOptions.toBundle();
12557                }
12558                return null;
12559            }
12560        } finally {
12561            Binder.restoreCallingIdentity(origId);
12562        }
12563    }
12564
12565    @Override
12566    public void setImmersive(IBinder token, boolean immersive) {
12567        synchronized(this) {
12568            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12569            if (r == null) {
12570                throw new IllegalArgumentException();
12571            }
12572            r.immersive = immersive;
12573
12574            // update associated state if we're frontmost
12575            if (r == mStackSupervisor.getResumedActivityLocked()) {
12576                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12577                applyUpdateLockStateLocked(r);
12578            }
12579        }
12580    }
12581
12582    @Override
12583    public boolean isImmersive(IBinder token) {
12584        synchronized (this) {
12585            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12586            if (r == null) {
12587                throw new IllegalArgumentException();
12588            }
12589            return r.immersive;
12590        }
12591    }
12592
12593    public void setVrThread(int tid) {
12594        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12595            throw new UnsupportedOperationException("VR mode not supported on this device!");
12596        }
12597
12598        synchronized (this) {
12599            ProcessRecord proc;
12600            synchronized (mPidsSelfLocked) {
12601                final int pid = Binder.getCallingPid();
12602                proc = mPidsSelfLocked.get(pid);
12603
12604                if (proc != null && mInVrMode && tid >= 0) {
12605                    // ensure the tid belongs to the process
12606                    if (!Process.isThreadInProcess(pid, tid)) {
12607                        throw new IllegalArgumentException("VR thread does not belong to process");
12608                    }
12609
12610                    // reset existing VR thread to CFS if this thread still exists and belongs to
12611                    // the calling process
12612                    if (proc.vrThreadTid != 0
12613                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12614                        try {
12615                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12616                        } catch (IllegalArgumentException e) {
12617                            // Ignore this.  Only occurs in race condition where previous VR thread
12618                            // was destroyed during this method call.
12619                        }
12620                    }
12621
12622                    proc.vrThreadTid = tid;
12623
12624                    // promote to FIFO now if the tid is non-zero
12625                    try {
12626                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12627                            proc.vrThreadTid > 0) {
12628                            Process.setThreadScheduler(proc.vrThreadTid,
12629                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12630                        }
12631                    } catch (IllegalArgumentException e) {
12632                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12633                               + " not exist:\n" + e);
12634                    }
12635                }
12636            }
12637        }
12638    }
12639
12640    @Override
12641    public void setRenderThread(int tid) {
12642        synchronized (this) {
12643            ProcessRecord proc;
12644            synchronized (mPidsSelfLocked) {
12645                int pid = Binder.getCallingPid();
12646                proc = mPidsSelfLocked.get(pid);
12647                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12648                    // ensure the tid belongs to the process
12649                    if (!Process.isThreadInProcess(pid, tid)) {
12650                        throw new IllegalArgumentException(
12651                            "Render thread does not belong to process");
12652                    }
12653                    proc.renderThreadTid = tid;
12654                    if (DEBUG_OOM_ADJ) {
12655                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12656                    }
12657                    // promote to FIFO now
12658                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12659                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12660                        if (mUseFifoUiScheduling) {
12661                            Process.setThreadScheduler(proc.renderThreadTid,
12662                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12663                        } else {
12664                            Process.setThreadPriority(proc.renderThreadTid, -10);
12665                        }
12666                    }
12667                } else {
12668                    if (DEBUG_OOM_ADJ) {
12669                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12670                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12671                               mUseFifoUiScheduling);
12672                    }
12673                }
12674            }
12675        }
12676    }
12677
12678    @Override
12679    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12680        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12681            throw new UnsupportedOperationException("VR mode not supported on this device!");
12682        }
12683
12684        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12685
12686        ActivityRecord r;
12687        synchronized (this) {
12688            r = ActivityRecord.isInStackLocked(token);
12689        }
12690
12691        if (r == null) {
12692            throw new IllegalArgumentException();
12693        }
12694
12695        int err;
12696        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12697                VrManagerInternal.NO_ERROR) {
12698            return err;
12699        }
12700
12701        synchronized(this) {
12702            r.requestedVrComponent = (enabled) ? packageName : null;
12703
12704            // Update associated state if this activity is currently focused
12705            if (r == mStackSupervisor.getResumedActivityLocked()) {
12706                applyUpdateVrModeLocked(r);
12707            }
12708            return 0;
12709        }
12710    }
12711
12712    @Override
12713    public boolean isVrModePackageEnabled(ComponentName packageName) {
12714        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12715            throw new UnsupportedOperationException("VR mode not supported on this device!");
12716        }
12717
12718        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12719
12720        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12721                VrManagerInternal.NO_ERROR;
12722    }
12723
12724    public boolean isTopActivityImmersive() {
12725        enforceNotIsolatedCaller("startActivity");
12726        synchronized (this) {
12727            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12728            return (r != null) ? r.immersive : false;
12729        }
12730    }
12731
12732    @Override
12733    public boolean isTopOfTask(IBinder token) {
12734        synchronized (this) {
12735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12736            if (r == null) {
12737                throw new IllegalArgumentException();
12738            }
12739            return r.task.getTopActivity() == r;
12740        }
12741    }
12742
12743    @Override
12744    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12745        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12746            String msg = "Permission Denial: setHasTopUi() from pid="
12747                    + Binder.getCallingPid()
12748                    + ", uid=" + Binder.getCallingUid()
12749                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12750            Slog.w(TAG, msg);
12751            throw new SecurityException(msg);
12752        }
12753        final int pid = Binder.getCallingPid();
12754        final long origId = Binder.clearCallingIdentity();
12755        try {
12756            synchronized (this) {
12757                boolean changed = false;
12758                ProcessRecord pr;
12759                synchronized (mPidsSelfLocked) {
12760                    pr = mPidsSelfLocked.get(pid);
12761                    if (pr == null) {
12762                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12763                        return;
12764                    }
12765                    if (pr.hasTopUi != hasTopUi) {
12766                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12767                        pr.hasTopUi = hasTopUi;
12768                        changed = true;
12769                    }
12770                }
12771                if (changed) {
12772                    updateOomAdjLocked(pr);
12773                }
12774            }
12775        } finally {
12776            Binder.restoreCallingIdentity(origId);
12777        }
12778    }
12779
12780    public final void enterSafeMode() {
12781        synchronized(this) {
12782            // It only makes sense to do this before the system is ready
12783            // and started launching other packages.
12784            if (!mSystemReady) {
12785                try {
12786                    AppGlobals.getPackageManager().enterSafeMode();
12787                } catch (RemoteException e) {
12788                }
12789            }
12790
12791            mSafeMode = true;
12792        }
12793    }
12794
12795    public final void showSafeModeOverlay() {
12796        View v = LayoutInflater.from(mContext).inflate(
12797                com.android.internal.R.layout.safe_mode, null);
12798        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12799        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12800        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12801        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12802        lp.gravity = Gravity.BOTTOM | Gravity.START;
12803        lp.format = v.getBackground().getOpacity();
12804        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12805                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12806        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12807        ((WindowManager)mContext.getSystemService(
12808                Context.WINDOW_SERVICE)).addView(v, lp);
12809    }
12810
12811    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12812        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12813            return;
12814        }
12815        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12816        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12817        synchronized (stats) {
12818            if (mBatteryStatsService.isOnBattery()) {
12819                mBatteryStatsService.enforceCallingPermission();
12820                int MY_UID = Binder.getCallingUid();
12821                final int uid;
12822                if (sender == null) {
12823                    uid = sourceUid;
12824                } else {
12825                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12826                }
12827                BatteryStatsImpl.Uid.Pkg pkg =
12828                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12829                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12830                pkg.noteWakeupAlarmLocked(tag);
12831            }
12832        }
12833    }
12834
12835    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12836        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12837            return;
12838        }
12839        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12840        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12841        synchronized (stats) {
12842            mBatteryStatsService.enforceCallingPermission();
12843            int MY_UID = Binder.getCallingUid();
12844            final int uid;
12845            if (sender == null) {
12846                uid = sourceUid;
12847            } else {
12848                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12849            }
12850            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12851        }
12852    }
12853
12854    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12855        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12856            return;
12857        }
12858        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12859        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12860        synchronized (stats) {
12861            mBatteryStatsService.enforceCallingPermission();
12862            int MY_UID = Binder.getCallingUid();
12863            final int uid;
12864            if (sender == null) {
12865                uid = sourceUid;
12866            } else {
12867                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12868            }
12869            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12870        }
12871    }
12872
12873    public boolean killPids(int[] pids, String pReason, boolean secure) {
12874        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12875            throw new SecurityException("killPids only available to the system");
12876        }
12877        String reason = (pReason == null) ? "Unknown" : pReason;
12878        // XXX Note: don't acquire main activity lock here, because the window
12879        // manager calls in with its locks held.
12880
12881        boolean killed = false;
12882        synchronized (mPidsSelfLocked) {
12883            int worstType = 0;
12884            for (int i=0; i<pids.length; i++) {
12885                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12886                if (proc != null) {
12887                    int type = proc.setAdj;
12888                    if (type > worstType) {
12889                        worstType = type;
12890                    }
12891                }
12892            }
12893
12894            // If the worst oom_adj is somewhere in the cached proc LRU range,
12895            // then constrain it so we will kill all cached procs.
12896            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12897                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12898                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12899            }
12900
12901            // If this is not a secure call, don't let it kill processes that
12902            // are important.
12903            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12904                worstType = ProcessList.SERVICE_ADJ;
12905            }
12906
12907            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12908            for (int i=0; i<pids.length; i++) {
12909                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12910                if (proc == null) {
12911                    continue;
12912                }
12913                int adj = proc.setAdj;
12914                if (adj >= worstType && !proc.killedByAm) {
12915                    proc.kill(reason, true);
12916                    killed = true;
12917                }
12918            }
12919        }
12920        return killed;
12921    }
12922
12923    @Override
12924    public void killUid(int appId, int userId, String reason) {
12925        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12926        synchronized (this) {
12927            final long identity = Binder.clearCallingIdentity();
12928            try {
12929                killPackageProcessesLocked(null, appId, userId,
12930                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12931                        reason != null ? reason : "kill uid");
12932            } finally {
12933                Binder.restoreCallingIdentity(identity);
12934            }
12935        }
12936    }
12937
12938    @Override
12939    public boolean killProcessesBelowForeground(String reason) {
12940        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12941            throw new SecurityException("killProcessesBelowForeground() only available to system");
12942        }
12943
12944        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12945    }
12946
12947    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12948        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12949            throw new SecurityException("killProcessesBelowAdj() only available to system");
12950        }
12951
12952        boolean killed = false;
12953        synchronized (mPidsSelfLocked) {
12954            final int size = mPidsSelfLocked.size();
12955            for (int i = 0; i < size; i++) {
12956                final int pid = mPidsSelfLocked.keyAt(i);
12957                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12958                if (proc == null) continue;
12959
12960                final int adj = proc.setAdj;
12961                if (adj > belowAdj && !proc.killedByAm) {
12962                    proc.kill(reason, true);
12963                    killed = true;
12964                }
12965            }
12966        }
12967        return killed;
12968    }
12969
12970    @Override
12971    public void hang(final IBinder who, boolean allowRestart) {
12972        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12973                != PackageManager.PERMISSION_GRANTED) {
12974            throw new SecurityException("Requires permission "
12975                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12976        }
12977
12978        final IBinder.DeathRecipient death = new DeathRecipient() {
12979            @Override
12980            public void binderDied() {
12981                synchronized (this) {
12982                    notifyAll();
12983                }
12984            }
12985        };
12986
12987        try {
12988            who.linkToDeath(death, 0);
12989        } catch (RemoteException e) {
12990            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12991            return;
12992        }
12993
12994        synchronized (this) {
12995            Watchdog.getInstance().setAllowRestart(allowRestart);
12996            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12997            synchronized (death) {
12998                while (who.isBinderAlive()) {
12999                    try {
13000                        death.wait();
13001                    } catch (InterruptedException e) {
13002                    }
13003                }
13004            }
13005            Watchdog.getInstance().setAllowRestart(true);
13006        }
13007    }
13008
13009    @Override
13010    public void restart() {
13011        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13012                != PackageManager.PERMISSION_GRANTED) {
13013            throw new SecurityException("Requires permission "
13014                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13015        }
13016
13017        Log.i(TAG, "Sending shutdown broadcast...");
13018
13019        BroadcastReceiver br = new BroadcastReceiver() {
13020            @Override public void onReceive(Context context, Intent intent) {
13021                // Now the broadcast is done, finish up the low-level shutdown.
13022                Log.i(TAG, "Shutting down activity manager...");
13023                shutdown(10000);
13024                Log.i(TAG, "Shutdown complete, restarting!");
13025                Process.killProcess(Process.myPid());
13026                System.exit(10);
13027            }
13028        };
13029
13030        // First send the high-level shut down broadcast.
13031        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13032        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13033        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13034        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13035        mContext.sendOrderedBroadcastAsUser(intent,
13036                UserHandle.ALL, null, br, mHandler, 0, null, null);
13037        */
13038        br.onReceive(mContext, intent);
13039    }
13040
13041    private long getLowRamTimeSinceIdle(long now) {
13042        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13043    }
13044
13045    @Override
13046    public void performIdleMaintenance() {
13047        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13048                != PackageManager.PERMISSION_GRANTED) {
13049            throw new SecurityException("Requires permission "
13050                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13051        }
13052
13053        synchronized (this) {
13054            final long now = SystemClock.uptimeMillis();
13055            final long timeSinceLastIdle = now - mLastIdleTime;
13056            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13057            mLastIdleTime = now;
13058            mLowRamTimeSinceLastIdle = 0;
13059            if (mLowRamStartTime != 0) {
13060                mLowRamStartTime = now;
13061            }
13062
13063            StringBuilder sb = new StringBuilder(128);
13064            sb.append("Idle maintenance over ");
13065            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13066            sb.append(" low RAM for ");
13067            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13068            Slog.i(TAG, sb.toString());
13069
13070            // If at least 1/3 of our time since the last idle period has been spent
13071            // with RAM low, then we want to kill processes.
13072            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13073
13074            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13075                ProcessRecord proc = mLruProcesses.get(i);
13076                if (proc.notCachedSinceIdle) {
13077                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13078                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13079                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13080                        if (doKilling && proc.initialIdlePss != 0
13081                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13082                            sb = new StringBuilder(128);
13083                            sb.append("Kill");
13084                            sb.append(proc.processName);
13085                            sb.append(" in idle maint: pss=");
13086                            sb.append(proc.lastPss);
13087                            sb.append(", swapPss=");
13088                            sb.append(proc.lastSwapPss);
13089                            sb.append(", initialPss=");
13090                            sb.append(proc.initialIdlePss);
13091                            sb.append(", period=");
13092                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13093                            sb.append(", lowRamPeriod=");
13094                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13095                            Slog.wtfQuiet(TAG, sb.toString());
13096                            proc.kill("idle maint (pss " + proc.lastPss
13097                                    + " from " + proc.initialIdlePss + ")", true);
13098                        }
13099                    }
13100                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13101                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13102                    proc.notCachedSinceIdle = true;
13103                    proc.initialIdlePss = 0;
13104                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13105                            mTestPssMode, isSleepingLocked(), now);
13106                }
13107            }
13108
13109            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13110            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13111        }
13112    }
13113
13114    @Override
13115    public void sendIdleJobTrigger() {
13116        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13117                != PackageManager.PERMISSION_GRANTED) {
13118            throw new SecurityException("Requires permission "
13119                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13120        }
13121
13122        final long ident = Binder.clearCallingIdentity();
13123        try {
13124            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13125                    .setPackage("android")
13126                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13127            broadcastIntent(null, intent, null, null, 0, null, null, null,
13128                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13129        } finally {
13130            Binder.restoreCallingIdentity(ident);
13131        }
13132    }
13133
13134    private void retrieveSettings() {
13135        final ContentResolver resolver = mContext.getContentResolver();
13136        final boolean freeformWindowManagement =
13137                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13138                        || Settings.Global.getInt(
13139                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13140        final boolean supportsPictureInPicture =
13141                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13142
13143        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13144        final boolean supportsSplitScreenMultiWindow =
13145                ActivityManager.supportsSplitScreenMultiWindow();
13146        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13147        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13148        final boolean alwaysFinishActivities =
13149                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13150        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13151        final boolean forceResizable = Settings.Global.getInt(
13152                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13153        final boolean supportsLeanbackOnly =
13154                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13155
13156        // Transfer any global setting for forcing RTL layout, into a System Property
13157        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13158
13159        final Configuration configuration = new Configuration();
13160        Settings.System.getConfiguration(resolver, configuration);
13161        if (forceRtl) {
13162            // This will take care of setting the correct layout direction flags
13163            configuration.setLayoutDirection(configuration.locale);
13164        }
13165
13166        synchronized (this) {
13167            mDebugApp = mOrigDebugApp = debugApp;
13168            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13169            mAlwaysFinishActivities = alwaysFinishActivities;
13170            mSupportsLeanbackOnly = supportsLeanbackOnly;
13171            mForceResizableActivities = forceResizable;
13172            if (supportsMultiWindow || forceResizable) {
13173                mSupportsMultiWindow = true;
13174                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13175                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13176            } else {
13177                mSupportsMultiWindow = false;
13178                mSupportsFreeformWindowManagement = false;
13179                mSupportsPictureInPicture = false;
13180            }
13181            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13182            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13183            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13184            // This happens before any activities are started, so we can change global configuration
13185            // in-place.
13186            updateConfigurationLocked(configuration, null, true);
13187            final Configuration globalConfig = getGlobalConfiguration();
13188            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13189
13190            // Load resources only after the current configuration has been set.
13191            final Resources res = mContext.getResources();
13192            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13193            mThumbnailWidth = res.getDimensionPixelSize(
13194                    com.android.internal.R.dimen.thumbnail_width);
13195            mThumbnailHeight = res.getDimensionPixelSize(
13196                    com.android.internal.R.dimen.thumbnail_height);
13197            mMinPipAspectRatio = res.getFloat(
13198                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
13199            mMaxPipAspectRatio = res.getFloat(
13200                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
13201            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13202                    com.android.internal.R.string.config_appsNotReportingCrashes));
13203            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13204                    com.android.internal.R.bool.config_customUserSwitchUi);
13205            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13206                mFullscreenThumbnailScale = (float) res
13207                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13208                    (float) globalConfig.screenWidthDp;
13209            } else {
13210                mFullscreenThumbnailScale = res.getFraction(
13211                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13212            }
13213        }
13214    }
13215
13216    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13217        traceLog.traceBegin("PhaseActivityManagerReady");
13218        synchronized(this) {
13219            if (mSystemReady) {
13220                // If we're done calling all the receivers, run the next "boot phase" passed in
13221                // by the SystemServer
13222                if (goingCallback != null) {
13223                    goingCallback.run();
13224                }
13225                return;
13226            }
13227
13228            mLocalDeviceIdleController
13229                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13230
13231            // Make sure we have the current profile info, since it is needed for security checks.
13232            mUserController.onSystemReady();
13233            mRecentTasks.onSystemReadyLocked();
13234            mAppOpsService.systemReady();
13235            mSystemReady = true;
13236        }
13237
13238        ArrayList<ProcessRecord> procsToKill = null;
13239        synchronized(mPidsSelfLocked) {
13240            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13241                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13242                if (!isAllowedWhileBooting(proc.info)){
13243                    if (procsToKill == null) {
13244                        procsToKill = new ArrayList<ProcessRecord>();
13245                    }
13246                    procsToKill.add(proc);
13247                }
13248            }
13249        }
13250
13251        synchronized(this) {
13252            if (procsToKill != null) {
13253                for (int i=procsToKill.size()-1; i>=0; i--) {
13254                    ProcessRecord proc = procsToKill.get(i);
13255                    Slog.i(TAG, "Removing system update proc: " + proc);
13256                    removeProcessLocked(proc, true, false, "system update done");
13257                }
13258            }
13259
13260            // Now that we have cleaned up any update processes, we
13261            // are ready to start launching real processes and know that
13262            // we won't trample on them any more.
13263            mProcessesReady = true;
13264        }
13265
13266        Slog.i(TAG, "System now ready");
13267        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13268            SystemClock.uptimeMillis());
13269
13270        synchronized(this) {
13271            // Make sure we have no pre-ready processes sitting around.
13272
13273            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13274                ResolveInfo ri = mContext.getPackageManager()
13275                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13276                                STOCK_PM_FLAGS);
13277                CharSequence errorMsg = null;
13278                if (ri != null) {
13279                    ActivityInfo ai = ri.activityInfo;
13280                    ApplicationInfo app = ai.applicationInfo;
13281                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13282                        mTopAction = Intent.ACTION_FACTORY_TEST;
13283                        mTopData = null;
13284                        mTopComponent = new ComponentName(app.packageName,
13285                                ai.name);
13286                    } else {
13287                        errorMsg = mContext.getResources().getText(
13288                                com.android.internal.R.string.factorytest_not_system);
13289                    }
13290                } else {
13291                    errorMsg = mContext.getResources().getText(
13292                            com.android.internal.R.string.factorytest_no_action);
13293                }
13294                if (errorMsg != null) {
13295                    mTopAction = null;
13296                    mTopData = null;
13297                    mTopComponent = null;
13298                    Message msg = Message.obtain();
13299                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13300                    msg.getData().putCharSequence("msg", errorMsg);
13301                    mUiHandler.sendMessage(msg);
13302                }
13303            }
13304        }
13305
13306        retrieveSettings();
13307        final int currentUserId;
13308        synchronized (this) {
13309            currentUserId = mUserController.getCurrentUserIdLocked();
13310            readGrantedUriPermissionsLocked();
13311        }
13312
13313        if (goingCallback != null) goingCallback.run();
13314        traceLog.traceBegin("ActivityManagerStartApps");
13315        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13316                Integer.toString(currentUserId), currentUserId);
13317        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13318                Integer.toString(currentUserId), currentUserId);
13319        mSystemServiceManager.startUser(currentUserId);
13320
13321        synchronized (this) {
13322            // Only start up encryption-aware persistent apps; once user is
13323            // unlocked we'll come back around and start unaware apps
13324            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13325
13326            // Start up initial activity.
13327            mBooting = true;
13328            // Enable home activity for system user, so that the system can always boot. We don't
13329            // do this when the system user is not setup since the setup wizard should be the one
13330            // to handle home activity in this case.
13331            if (UserManager.isSplitSystemUser() &&
13332                    Settings.Secure.getInt(mContext.getContentResolver(),
13333                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13334                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13335                try {
13336                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13337                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13338                            UserHandle.USER_SYSTEM);
13339                } catch (RemoteException e) {
13340                    throw e.rethrowAsRuntimeException();
13341                }
13342            }
13343            startHomeActivityLocked(currentUserId, "systemReady");
13344
13345            try {
13346                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13347                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13348                            + " data partition or your device will be unstable.");
13349                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13350                }
13351            } catch (RemoteException e) {
13352            }
13353
13354            if (!Build.isBuildConsistent()) {
13355                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13356                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13357            }
13358
13359            long ident = Binder.clearCallingIdentity();
13360            try {
13361                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13362                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13363                        | Intent.FLAG_RECEIVER_FOREGROUND);
13364                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13365                broadcastIntentLocked(null, null, intent,
13366                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13367                        null, false, false, MY_PID, Process.SYSTEM_UID,
13368                        currentUserId);
13369                intent = new Intent(Intent.ACTION_USER_STARTING);
13370                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13371                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13372                broadcastIntentLocked(null, null, intent,
13373                        null, new IIntentReceiver.Stub() {
13374                            @Override
13375                            public void performReceive(Intent intent, int resultCode, String data,
13376                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13377                                    throws RemoteException {
13378                            }
13379                        }, 0, null, null,
13380                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13381                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13382            } catch (Throwable t) {
13383                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13384            } finally {
13385                Binder.restoreCallingIdentity(ident);
13386            }
13387            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13388            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13389            traceLog.traceEnd(); // ActivityManagerStartApps
13390            traceLog.traceEnd(); // PhaseActivityManagerReady
13391        }
13392    }
13393
13394    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13395        synchronized (this) {
13396            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13397        }
13398    }
13399
13400    void skipCurrentReceiverLocked(ProcessRecord app) {
13401        for (BroadcastQueue queue : mBroadcastQueues) {
13402            queue.skipCurrentReceiverLocked(app);
13403        }
13404    }
13405
13406    /**
13407     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13408     * The application process will exit immediately after this call returns.
13409     * @param app object of the crashing app, null for the system server
13410     * @param crashInfo describing the exception
13411     */
13412    public void handleApplicationCrash(IBinder app,
13413            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13414        ProcessRecord r = findAppProcess(app, "Crash");
13415        final String processName = app == null ? "system_server"
13416                : (r == null ? "unknown" : r.processName);
13417
13418        handleApplicationCrashInner("crash", r, processName, crashInfo);
13419    }
13420
13421    /* Native crash reporting uses this inner version because it needs to be somewhat
13422     * decoupled from the AM-managed cleanup lifecycle
13423     */
13424    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13425            ApplicationErrorReport.CrashInfo crashInfo) {
13426        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13427                UserHandle.getUserId(Binder.getCallingUid()), processName,
13428                r == null ? -1 : r.info.flags,
13429                crashInfo.exceptionClassName,
13430                crashInfo.exceptionMessage,
13431                crashInfo.throwFileName,
13432                crashInfo.throwLineNumber);
13433
13434        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13435
13436        mAppErrors.crashApplication(r, crashInfo);
13437    }
13438
13439    public void handleApplicationStrictModeViolation(
13440            IBinder app,
13441            int violationMask,
13442            StrictMode.ViolationInfo info) {
13443        ProcessRecord r = findAppProcess(app, "StrictMode");
13444        if (r == null) {
13445            return;
13446        }
13447
13448        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13449            Integer stackFingerprint = info.hashCode();
13450            boolean logIt = true;
13451            synchronized (mAlreadyLoggedViolatedStacks) {
13452                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13453                    logIt = false;
13454                    // TODO: sub-sample into EventLog for these, with
13455                    // the info.durationMillis?  Then we'd get
13456                    // the relative pain numbers, without logging all
13457                    // the stack traces repeatedly.  We'd want to do
13458                    // likewise in the client code, which also does
13459                    // dup suppression, before the Binder call.
13460                } else {
13461                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13462                        mAlreadyLoggedViolatedStacks.clear();
13463                    }
13464                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13465                }
13466            }
13467            if (logIt) {
13468                logStrictModeViolationToDropBox(r, info);
13469            }
13470        }
13471
13472        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13473            AppErrorResult result = new AppErrorResult();
13474            synchronized (this) {
13475                final long origId = Binder.clearCallingIdentity();
13476
13477                Message msg = Message.obtain();
13478                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13479                HashMap<String, Object> data = new HashMap<String, Object>();
13480                data.put("result", result);
13481                data.put("app", r);
13482                data.put("violationMask", violationMask);
13483                data.put("info", info);
13484                msg.obj = data;
13485                mUiHandler.sendMessage(msg);
13486
13487                Binder.restoreCallingIdentity(origId);
13488            }
13489            int res = result.get();
13490            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13491        }
13492    }
13493
13494    // Depending on the policy in effect, there could be a bunch of
13495    // these in quick succession so we try to batch these together to
13496    // minimize disk writes, number of dropbox entries, and maximize
13497    // compression, by having more fewer, larger records.
13498    private void logStrictModeViolationToDropBox(
13499            ProcessRecord process,
13500            StrictMode.ViolationInfo info) {
13501        if (info == null) {
13502            return;
13503        }
13504        final boolean isSystemApp = process == null ||
13505                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13506                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13507        final String processName = process == null ? "unknown" : process.processName;
13508        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13509        final DropBoxManager dbox = (DropBoxManager)
13510                mContext.getSystemService(Context.DROPBOX_SERVICE);
13511
13512        // Exit early if the dropbox isn't configured to accept this report type.
13513        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13514
13515        boolean bufferWasEmpty;
13516        boolean needsFlush;
13517        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13518        synchronized (sb) {
13519            bufferWasEmpty = sb.length() == 0;
13520            appendDropBoxProcessHeaders(process, processName, sb);
13521            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13522            sb.append("System-App: ").append(isSystemApp).append("\n");
13523            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13524            if (info.violationNumThisLoop != 0) {
13525                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13526            }
13527            if (info.numAnimationsRunning != 0) {
13528                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13529            }
13530            if (info.broadcastIntentAction != null) {
13531                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13532            }
13533            if (info.durationMillis != -1) {
13534                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13535            }
13536            if (info.numInstances != -1) {
13537                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13538            }
13539            if (info.tags != null) {
13540                for (String tag : info.tags) {
13541                    sb.append("Span-Tag: ").append(tag).append("\n");
13542                }
13543            }
13544            sb.append("\n");
13545            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13546                sb.append(info.crashInfo.stackTrace);
13547                sb.append("\n");
13548            }
13549            if (info.message != null) {
13550                sb.append(info.message);
13551                sb.append("\n");
13552            }
13553
13554            // Only buffer up to ~64k.  Various logging bits truncate
13555            // things at 128k.
13556            needsFlush = (sb.length() > 64 * 1024);
13557        }
13558
13559        // Flush immediately if the buffer's grown too large, or this
13560        // is a non-system app.  Non-system apps are isolated with a
13561        // different tag & policy and not batched.
13562        //
13563        // Batching is useful during internal testing with
13564        // StrictMode settings turned up high.  Without batching,
13565        // thousands of separate files could be created on boot.
13566        if (!isSystemApp || needsFlush) {
13567            new Thread("Error dump: " + dropboxTag) {
13568                @Override
13569                public void run() {
13570                    String report;
13571                    synchronized (sb) {
13572                        report = sb.toString();
13573                        sb.delete(0, sb.length());
13574                        sb.trimToSize();
13575                    }
13576                    if (report.length() != 0) {
13577                        dbox.addText(dropboxTag, report);
13578                    }
13579                }
13580            }.start();
13581            return;
13582        }
13583
13584        // System app batching:
13585        if (!bufferWasEmpty) {
13586            // An existing dropbox-writing thread is outstanding, so
13587            // we don't need to start it up.  The existing thread will
13588            // catch the buffer appends we just did.
13589            return;
13590        }
13591
13592        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13593        // (After this point, we shouldn't access AMS internal data structures.)
13594        new Thread("Error dump: " + dropboxTag) {
13595            @Override
13596            public void run() {
13597                // 5 second sleep to let stacks arrive and be batched together
13598                try {
13599                    Thread.sleep(5000);  // 5 seconds
13600                } catch (InterruptedException e) {}
13601
13602                String errorReport;
13603                synchronized (mStrictModeBuffer) {
13604                    errorReport = mStrictModeBuffer.toString();
13605                    if (errorReport.length() == 0) {
13606                        return;
13607                    }
13608                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13609                    mStrictModeBuffer.trimToSize();
13610                }
13611                dbox.addText(dropboxTag, errorReport);
13612            }
13613        }.start();
13614    }
13615
13616    /**
13617     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13618     * @param app object of the crashing app, null for the system server
13619     * @param tag reported by the caller
13620     * @param system whether this wtf is coming from the system
13621     * @param crashInfo describing the context of the error
13622     * @return true if the process should exit immediately (WTF is fatal)
13623     */
13624    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13625            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13626        final int callingUid = Binder.getCallingUid();
13627        final int callingPid = Binder.getCallingPid();
13628
13629        if (system) {
13630            // If this is coming from the system, we could very well have low-level
13631            // system locks held, so we want to do this all asynchronously.  And we
13632            // never want this to become fatal, so there is that too.
13633            mHandler.post(new Runnable() {
13634                @Override public void run() {
13635                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13636                }
13637            });
13638            return false;
13639        }
13640
13641        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13642                crashInfo);
13643
13644        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
13645                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
13646        final boolean isSystem = (r == null) || r.persistent;
13647
13648        if (isFatal && !isSystem) {
13649            mAppErrors.crashApplication(r, crashInfo);
13650            return true;
13651        } else {
13652            return false;
13653        }
13654    }
13655
13656    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13657            final ApplicationErrorReport.CrashInfo crashInfo) {
13658        final ProcessRecord r = findAppProcess(app, "WTF");
13659        final String processName = app == null ? "system_server"
13660                : (r == null ? "unknown" : r.processName);
13661
13662        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13663                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13664
13665        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13666
13667        return r;
13668    }
13669
13670    /**
13671     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13672     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13673     */
13674    private ProcessRecord findAppProcess(IBinder app, String reason) {
13675        if (app == null) {
13676            return null;
13677        }
13678
13679        synchronized (this) {
13680            final int NP = mProcessNames.getMap().size();
13681            for (int ip=0; ip<NP; ip++) {
13682                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13683                final int NA = apps.size();
13684                for (int ia=0; ia<NA; ia++) {
13685                    ProcessRecord p = apps.valueAt(ia);
13686                    if (p.thread != null && p.thread.asBinder() == app) {
13687                        return p;
13688                    }
13689                }
13690            }
13691
13692            Slog.w(TAG, "Can't find mystery application for " + reason
13693                    + " from pid=" + Binder.getCallingPid()
13694                    + " uid=" + Binder.getCallingUid() + ": " + app);
13695            return null;
13696        }
13697    }
13698
13699    /**
13700     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13701     * to append various headers to the dropbox log text.
13702     */
13703    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13704            StringBuilder sb) {
13705        // Watchdog thread ends up invoking this function (with
13706        // a null ProcessRecord) to add the stack file to dropbox.
13707        // Do not acquire a lock on this (am) in such cases, as it
13708        // could cause a potential deadlock, if and when watchdog
13709        // is invoked due to unavailability of lock on am and it
13710        // would prevent watchdog from killing system_server.
13711        if (process == null) {
13712            sb.append("Process: ").append(processName).append("\n");
13713            return;
13714        }
13715        // Note: ProcessRecord 'process' is guarded by the service
13716        // instance.  (notably process.pkgList, which could otherwise change
13717        // concurrently during execution of this method)
13718        synchronized (this) {
13719            sb.append("Process: ").append(processName).append("\n");
13720            int flags = process.info.flags;
13721            IPackageManager pm = AppGlobals.getPackageManager();
13722            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13723            for (int ip=0; ip<process.pkgList.size(); ip++) {
13724                String pkg = process.pkgList.keyAt(ip);
13725                sb.append("Package: ").append(pkg);
13726                try {
13727                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13728                    if (pi != null) {
13729                        sb.append(" v").append(pi.versionCode);
13730                        if (pi.versionName != null) {
13731                            sb.append(" (").append(pi.versionName).append(")");
13732                        }
13733                    }
13734                } catch (RemoteException e) {
13735                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13736                }
13737                sb.append("\n");
13738            }
13739        }
13740    }
13741
13742    private static String processClass(ProcessRecord process) {
13743        if (process == null || process.pid == MY_PID) {
13744            return "system_server";
13745        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13746            return "system_app";
13747        } else {
13748            return "data_app";
13749        }
13750    }
13751
13752    private volatile long mWtfClusterStart;
13753    private volatile int mWtfClusterCount;
13754
13755    /**
13756     * Write a description of an error (crash, WTF, ANR) to the drop box.
13757     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13758     * @param process which caused the error, null means the system server
13759     * @param activity which triggered the error, null if unknown
13760     * @param parent activity related to the error, null if unknown
13761     * @param subject line related to the error, null if absent
13762     * @param report in long form describing the error, null if absent
13763     * @param dataFile text file to include in the report, null if none
13764     * @param crashInfo giving an application stack trace, null if absent
13765     */
13766    public void addErrorToDropBox(String eventType,
13767            ProcessRecord process, String processName, ActivityRecord activity,
13768            ActivityRecord parent, String subject,
13769            final String report, final File dataFile,
13770            final ApplicationErrorReport.CrashInfo crashInfo) {
13771        // NOTE -- this must never acquire the ActivityManagerService lock,
13772        // otherwise the watchdog may be prevented from resetting the system.
13773
13774        // Bail early if not published yet
13775        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13776        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13777
13778        // Exit early if the dropbox isn't configured to accept this report type.
13779        final String dropboxTag = processClass(process) + "_" + eventType;
13780        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13781
13782        // Rate-limit how often we're willing to do the heavy lifting below to
13783        // collect and record logs; currently 5 logs per 10 second period.
13784        final long now = SystemClock.elapsedRealtime();
13785        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13786            mWtfClusterStart = now;
13787            mWtfClusterCount = 1;
13788        } else {
13789            if (mWtfClusterCount++ >= 5) return;
13790        }
13791
13792        final StringBuilder sb = new StringBuilder(1024);
13793        appendDropBoxProcessHeaders(process, processName, sb);
13794        if (process != null) {
13795            sb.append("Foreground: ")
13796                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13797                    .append("\n");
13798        }
13799        if (activity != null) {
13800            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13801        }
13802        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13803            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13804        }
13805        if (parent != null && parent != activity) {
13806            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13807        }
13808        if (subject != null) {
13809            sb.append("Subject: ").append(subject).append("\n");
13810        }
13811        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13812        if (Debug.isDebuggerConnected()) {
13813            sb.append("Debugger: Connected\n");
13814        }
13815        sb.append("\n");
13816
13817        // Do the rest in a worker thread to avoid blocking the caller on I/O
13818        // (After this point, we shouldn't access AMS internal data structures.)
13819        Thread worker = new Thread("Error dump: " + dropboxTag) {
13820            @Override
13821            public void run() {
13822                if (report != null) {
13823                    sb.append(report);
13824                }
13825
13826                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13827                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13828                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13829                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13830
13831                if (dataFile != null && maxDataFileSize > 0) {
13832                    try {
13833                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13834                                    "\n\n[[TRUNCATED]]"));
13835                    } catch (IOException e) {
13836                        Slog.e(TAG, "Error reading " + dataFile, e);
13837                    }
13838                }
13839                if (crashInfo != null && crashInfo.stackTrace != null) {
13840                    sb.append(crashInfo.stackTrace);
13841                }
13842
13843                if (lines > 0) {
13844                    sb.append("\n");
13845
13846                    // Merge several logcat streams, and take the last N lines
13847                    InputStreamReader input = null;
13848                    try {
13849                        java.lang.Process logcat = new ProcessBuilder(
13850                                "/system/bin/timeout", "-k", "15s", "10s",
13851                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13852                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13853                                        .redirectErrorStream(true).start();
13854
13855                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13856                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13857                        input = new InputStreamReader(logcat.getInputStream());
13858
13859                        int num;
13860                        char[] buf = new char[8192];
13861                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13862                    } catch (IOException e) {
13863                        Slog.e(TAG, "Error running logcat", e);
13864                    } finally {
13865                        if (input != null) try { input.close(); } catch (IOException e) {}
13866                    }
13867                }
13868
13869                dbox.addText(dropboxTag, sb.toString());
13870            }
13871        };
13872
13873        if (process == null) {
13874            // If process is null, we are being called from some internal code
13875            // and may be about to die -- run this synchronously.
13876            worker.run();
13877        } else {
13878            worker.start();
13879        }
13880    }
13881
13882    @Override
13883    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13884        enforceNotIsolatedCaller("getProcessesInErrorState");
13885        // assume our apps are happy - lazy create the list
13886        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13887
13888        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13889                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13890        int userId = UserHandle.getUserId(Binder.getCallingUid());
13891
13892        synchronized (this) {
13893
13894            // iterate across all processes
13895            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13896                ProcessRecord app = mLruProcesses.get(i);
13897                if (!allUsers && app.userId != userId) {
13898                    continue;
13899                }
13900                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13901                    // This one's in trouble, so we'll generate a report for it
13902                    // crashes are higher priority (in case there's a crash *and* an anr)
13903                    ActivityManager.ProcessErrorStateInfo report = null;
13904                    if (app.crashing) {
13905                        report = app.crashingReport;
13906                    } else if (app.notResponding) {
13907                        report = app.notRespondingReport;
13908                    }
13909
13910                    if (report != null) {
13911                        if (errList == null) {
13912                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13913                        }
13914                        errList.add(report);
13915                    } else {
13916                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13917                                " crashing = " + app.crashing +
13918                                " notResponding = " + app.notResponding);
13919                    }
13920                }
13921            }
13922        }
13923
13924        return errList;
13925    }
13926
13927    static int procStateToImportance(int procState, int memAdj,
13928            ActivityManager.RunningAppProcessInfo currApp) {
13929        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13930        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13931            currApp.lru = memAdj;
13932        } else {
13933            currApp.lru = 0;
13934        }
13935        return imp;
13936    }
13937
13938    private void fillInProcMemInfo(ProcessRecord app,
13939            ActivityManager.RunningAppProcessInfo outInfo) {
13940        outInfo.pid = app.pid;
13941        outInfo.uid = app.info.uid;
13942        if (mHeavyWeightProcess == app) {
13943            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13944        }
13945        if (app.persistent) {
13946            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13947        }
13948        if (app.activities.size() > 0) {
13949            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13950        }
13951        outInfo.lastTrimLevel = app.trimMemoryLevel;
13952        int adj = app.curAdj;
13953        int procState = app.curProcState;
13954        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13955        outInfo.importanceReasonCode = app.adjTypeCode;
13956        outInfo.processState = app.curProcState;
13957    }
13958
13959    @Override
13960    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13961        enforceNotIsolatedCaller("getRunningAppProcesses");
13962
13963        final int callingUid = Binder.getCallingUid();
13964
13965        // Lazy instantiation of list
13966        List<ActivityManager.RunningAppProcessInfo> runList = null;
13967        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13968                callingUid) == PackageManager.PERMISSION_GRANTED;
13969        final int userId = UserHandle.getUserId(callingUid);
13970        final boolean allUids = isGetTasksAllowed(
13971                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13972
13973        synchronized (this) {
13974            // Iterate across all processes
13975            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13976                ProcessRecord app = mLruProcesses.get(i);
13977                if ((!allUsers && app.userId != userId)
13978                        || (!allUids && app.uid != callingUid)) {
13979                    continue;
13980                }
13981                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13982                    // Generate process state info for running application
13983                    ActivityManager.RunningAppProcessInfo currApp =
13984                        new ActivityManager.RunningAppProcessInfo(app.processName,
13985                                app.pid, app.getPackageList());
13986                    fillInProcMemInfo(app, currApp);
13987                    if (app.adjSource instanceof ProcessRecord) {
13988                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13989                        currApp.importanceReasonImportance =
13990                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13991                                        app.adjSourceProcState);
13992                    } else if (app.adjSource instanceof ActivityRecord) {
13993                        ActivityRecord r = (ActivityRecord)app.adjSource;
13994                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13995                    }
13996                    if (app.adjTarget instanceof ComponentName) {
13997                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13998                    }
13999                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14000                    //        + " lru=" + currApp.lru);
14001                    if (runList == null) {
14002                        runList = new ArrayList<>();
14003                    }
14004                    runList.add(currApp);
14005                }
14006            }
14007        }
14008        return runList;
14009    }
14010
14011    @Override
14012    public List<ApplicationInfo> getRunningExternalApplications() {
14013        enforceNotIsolatedCaller("getRunningExternalApplications");
14014        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14015        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14016        if (runningApps != null && runningApps.size() > 0) {
14017            Set<String> extList = new HashSet<String>();
14018            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14019                if (app.pkgList != null) {
14020                    for (String pkg : app.pkgList) {
14021                        extList.add(pkg);
14022                    }
14023                }
14024            }
14025            IPackageManager pm = AppGlobals.getPackageManager();
14026            for (String pkg : extList) {
14027                try {
14028                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14029                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14030                        retList.add(info);
14031                    }
14032                } catch (RemoteException e) {
14033                }
14034            }
14035        }
14036        return retList;
14037    }
14038
14039    @Override
14040    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14041        enforceNotIsolatedCaller("getMyMemoryState");
14042        synchronized (this) {
14043            ProcessRecord proc;
14044            synchronized (mPidsSelfLocked) {
14045                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14046            }
14047            fillInProcMemInfo(proc, outInfo);
14048        }
14049    }
14050
14051    @Override
14052    public int getMemoryTrimLevel() {
14053        enforceNotIsolatedCaller("getMyMemoryState");
14054        synchronized (this) {
14055            return mLastMemoryLevel;
14056        }
14057    }
14058
14059    @Override
14060    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14061            FileDescriptor err, String[] args, ShellCallback callback,
14062            ResultReceiver resultReceiver) {
14063        (new ActivityManagerShellCommand(this, false)).exec(
14064                this, in, out, err, args, callback, resultReceiver);
14065    }
14066
14067    @Override
14068    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14069        if (checkCallingPermission(android.Manifest.permission.DUMP)
14070                != PackageManager.PERMISSION_GRANTED) {
14071            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14072                    + Binder.getCallingPid()
14073                    + ", uid=" + Binder.getCallingUid()
14074                    + " without permission "
14075                    + android.Manifest.permission.DUMP);
14076            return;
14077        }
14078
14079        boolean dumpAll = false;
14080        boolean dumpClient = false;
14081        boolean dumpCheckin = false;
14082        boolean dumpCheckinFormat = false;
14083        boolean dumpVisibleStacks = false;
14084        String dumpPackage = null;
14085
14086        int opti = 0;
14087        while (opti < args.length) {
14088            String opt = args[opti];
14089            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14090                break;
14091            }
14092            opti++;
14093            if ("-a".equals(opt)) {
14094                dumpAll = true;
14095            } else if ("-c".equals(opt)) {
14096                dumpClient = true;
14097            } else if ("-v".equals(opt)) {
14098                dumpVisibleStacks = true;
14099            } else if ("-p".equals(opt)) {
14100                if (opti < args.length) {
14101                    dumpPackage = args[opti];
14102                    opti++;
14103                } else {
14104                    pw.println("Error: -p option requires package argument");
14105                    return;
14106                }
14107                dumpClient = true;
14108            } else if ("--checkin".equals(opt)) {
14109                dumpCheckin = dumpCheckinFormat = true;
14110            } else if ("-C".equals(opt)) {
14111                dumpCheckinFormat = true;
14112            } else if ("-h".equals(opt)) {
14113                ActivityManagerShellCommand.dumpHelp(pw, true);
14114                return;
14115            } else {
14116                pw.println("Unknown argument: " + opt + "; use -h for help");
14117            }
14118        }
14119
14120        long origId = Binder.clearCallingIdentity();
14121        boolean more = false;
14122        // Is the caller requesting to dump a particular piece of data?
14123        if (opti < args.length) {
14124            String cmd = args[opti];
14125            opti++;
14126            if ("activities".equals(cmd) || "a".equals(cmd)) {
14127                synchronized (this) {
14128                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14129                }
14130            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14131                synchronized (this) {
14132                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14133                }
14134            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14135                String[] newArgs;
14136                String name;
14137                if (opti >= args.length) {
14138                    name = null;
14139                    newArgs = EMPTY_STRING_ARRAY;
14140                } else {
14141                    dumpPackage = args[opti];
14142                    opti++;
14143                    newArgs = new String[args.length - opti];
14144                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14145                            args.length - opti);
14146                }
14147                synchronized (this) {
14148                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14149                }
14150            } else if ("broadcast-stats".equals(cmd)) {
14151                String[] newArgs;
14152                String name;
14153                if (opti >= args.length) {
14154                    name = null;
14155                    newArgs = EMPTY_STRING_ARRAY;
14156                } else {
14157                    dumpPackage = args[opti];
14158                    opti++;
14159                    newArgs = new String[args.length - opti];
14160                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14161                            args.length - opti);
14162                }
14163                synchronized (this) {
14164                    if (dumpCheckinFormat) {
14165                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14166                                dumpPackage);
14167                    } else {
14168                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14169                    }
14170                }
14171            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14172                String[] newArgs;
14173                String name;
14174                if (opti >= args.length) {
14175                    name = null;
14176                    newArgs = EMPTY_STRING_ARRAY;
14177                } else {
14178                    dumpPackage = args[opti];
14179                    opti++;
14180                    newArgs = new String[args.length - opti];
14181                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14182                            args.length - opti);
14183                }
14184                synchronized (this) {
14185                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14186                }
14187            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14188                String[] newArgs;
14189                String name;
14190                if (opti >= args.length) {
14191                    name = null;
14192                    newArgs = EMPTY_STRING_ARRAY;
14193                } else {
14194                    dumpPackage = args[opti];
14195                    opti++;
14196                    newArgs = new String[args.length - opti];
14197                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14198                            args.length - opti);
14199                }
14200                synchronized (this) {
14201                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14202                }
14203            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14204                synchronized (this) {
14205                    dumpOomLocked(fd, pw, args, opti, true);
14206                }
14207            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14208                synchronized (this) {
14209                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14210                }
14211            } else if ("provider".equals(cmd)) {
14212                String[] newArgs;
14213                String name;
14214                if (opti >= args.length) {
14215                    name = null;
14216                    newArgs = EMPTY_STRING_ARRAY;
14217                } else {
14218                    name = args[opti];
14219                    opti++;
14220                    newArgs = new String[args.length - opti];
14221                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14222                }
14223                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14224                    pw.println("No providers match: " + name);
14225                    pw.println("Use -h for help.");
14226                }
14227            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14228                synchronized (this) {
14229                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14230                }
14231            } else if ("service".equals(cmd)) {
14232                String[] newArgs;
14233                String name;
14234                if (opti >= args.length) {
14235                    name = null;
14236                    newArgs = EMPTY_STRING_ARRAY;
14237                } else {
14238                    name = args[opti];
14239                    opti++;
14240                    newArgs = new String[args.length - opti];
14241                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14242                            args.length - opti);
14243                }
14244                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14245                    pw.println("No services match: " + name);
14246                    pw.println("Use -h for help.");
14247                }
14248            } else if ("package".equals(cmd)) {
14249                String[] newArgs;
14250                if (opti >= args.length) {
14251                    pw.println("package: no package name specified");
14252                    pw.println("Use -h for help.");
14253                } else {
14254                    dumpPackage = args[opti];
14255                    opti++;
14256                    newArgs = new String[args.length - opti];
14257                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14258                            args.length - opti);
14259                    args = newArgs;
14260                    opti = 0;
14261                    more = true;
14262                }
14263            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14264                synchronized (this) {
14265                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14266                }
14267            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14268                if (dumpClient) {
14269                    ActiveServices.ServiceDumper dumper;
14270                    synchronized (this) {
14271                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14272                                dumpPackage);
14273                    }
14274                    dumper.dumpWithClient();
14275                } else {
14276                    synchronized (this) {
14277                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14278                                dumpPackage).dumpLocked();
14279                    }
14280                }
14281            } else if ("locks".equals(cmd)) {
14282                LockGuard.dump(fd, pw, args);
14283            } else {
14284                // Dumping a single activity?
14285                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14286                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14287                    int res = shell.exec(this, null, fd, null, args, null,
14288                            new ResultReceiver(null));
14289                    if (res < 0) {
14290                        pw.println("Bad activity command, or no activities match: " + cmd);
14291                        pw.println("Use -h for help.");
14292                    }
14293                }
14294            }
14295            if (!more) {
14296                Binder.restoreCallingIdentity(origId);
14297                return;
14298            }
14299        }
14300
14301        // No piece of data specified, dump everything.
14302        if (dumpCheckinFormat) {
14303            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14304        } else if (dumpClient) {
14305            ActiveServices.ServiceDumper sdumper;
14306            synchronized (this) {
14307                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14308                pw.println();
14309                if (dumpAll) {
14310                    pw.println("-------------------------------------------------------------------------------");
14311                }
14312                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14313                pw.println();
14314                if (dumpAll) {
14315                    pw.println("-------------------------------------------------------------------------------");
14316                }
14317                if (dumpAll || dumpPackage != null) {
14318                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14319                    pw.println();
14320                    if (dumpAll) {
14321                        pw.println("-------------------------------------------------------------------------------");
14322                    }
14323                }
14324                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14325                pw.println();
14326                if (dumpAll) {
14327                    pw.println("-------------------------------------------------------------------------------");
14328                }
14329                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14330                pw.println();
14331                if (dumpAll) {
14332                    pw.println("-------------------------------------------------------------------------------");
14333                }
14334                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14335                        dumpPackage);
14336            }
14337            sdumper.dumpWithClient();
14338            pw.println();
14339            synchronized (this) {
14340                if (dumpAll) {
14341                    pw.println("-------------------------------------------------------------------------------");
14342                }
14343                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14344                pw.println();
14345                if (dumpAll) {
14346                    pw.println("-------------------------------------------------------------------------------");
14347                }
14348                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14349                if (mAssociations.size() > 0) {
14350                    pw.println();
14351                    if (dumpAll) {
14352                        pw.println("-------------------------------------------------------------------------------");
14353                    }
14354                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14355                }
14356                pw.println();
14357                if (dumpAll) {
14358                    pw.println("-------------------------------------------------------------------------------");
14359                }
14360                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14361            }
14362
14363        } else {
14364            synchronized (this) {
14365                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14366                pw.println();
14367                if (dumpAll) {
14368                    pw.println("-------------------------------------------------------------------------------");
14369                }
14370                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14371                pw.println();
14372                if (dumpAll) {
14373                    pw.println("-------------------------------------------------------------------------------");
14374                }
14375                if (dumpAll || dumpPackage != null) {
14376                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14377                    pw.println();
14378                    if (dumpAll) {
14379                        pw.println("-------------------------------------------------------------------------------");
14380                    }
14381                }
14382                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14383                pw.println();
14384                if (dumpAll) {
14385                    pw.println("-------------------------------------------------------------------------------");
14386                }
14387                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14388                pw.println();
14389                if (dumpAll) {
14390                    pw.println("-------------------------------------------------------------------------------");
14391                }
14392                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14393                        .dumpLocked();
14394                pw.println();
14395                if (dumpAll) {
14396                    pw.println("-------------------------------------------------------------------------------");
14397                }
14398                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14399                pw.println();
14400                if (dumpAll) {
14401                    pw.println("-------------------------------------------------------------------------------");
14402                }
14403                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14404                if (mAssociations.size() > 0) {
14405                    pw.println();
14406                    if (dumpAll) {
14407                        pw.println("-------------------------------------------------------------------------------");
14408                    }
14409                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14410                }
14411                pw.println();
14412                if (dumpAll) {
14413                    pw.println("-------------------------------------------------------------------------------");
14414                }
14415                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14416            }
14417        }
14418        Binder.restoreCallingIdentity(origId);
14419    }
14420
14421    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14422            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14423        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14424
14425        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14426                dumpPackage);
14427        boolean needSep = printedAnything;
14428
14429        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14430                mStackSupervisor.getResumedActivityLocked(),
14431                dumpPackage, needSep, "  ResumedActivity: ");
14432        if (printed) {
14433            printedAnything = true;
14434            needSep = false;
14435        }
14436
14437        if (dumpPackage == null) {
14438            if (needSep) {
14439                pw.println();
14440            }
14441            needSep = true;
14442            printedAnything = true;
14443            mStackSupervisor.dump(pw, "  ");
14444        }
14445
14446        if (!printedAnything) {
14447            pw.println("  (nothing)");
14448        }
14449    }
14450
14451    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14452            int opti, boolean dumpAll, String dumpPackage) {
14453        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14454
14455        boolean printedAnything = false;
14456
14457        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14458            boolean printedHeader = false;
14459
14460            final int N = mRecentTasks.size();
14461            for (int i=0; i<N; i++) {
14462                TaskRecord tr = mRecentTasks.get(i);
14463                if (dumpPackage != null) {
14464                    if (tr.realActivity == null ||
14465                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14466                        continue;
14467                    }
14468                }
14469                if (!printedHeader) {
14470                    pw.println("  Recent tasks:");
14471                    printedHeader = true;
14472                    printedAnything = true;
14473                }
14474                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14475                        pw.println(tr);
14476                if (dumpAll) {
14477                    mRecentTasks.get(i).dump(pw, "    ");
14478                }
14479            }
14480        }
14481
14482        if (!printedAnything) {
14483            pw.println("  (nothing)");
14484        }
14485    }
14486
14487    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14488            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14489        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14490
14491        int dumpUid = 0;
14492        if (dumpPackage != null) {
14493            IPackageManager pm = AppGlobals.getPackageManager();
14494            try {
14495                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
14496            } catch (RemoteException e) {
14497            }
14498        }
14499
14500        boolean printedAnything = false;
14501
14502        final long now = SystemClock.uptimeMillis();
14503
14504        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14505            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14506                    = mAssociations.valueAt(i1);
14507            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14508                SparseArray<ArrayMap<String, Association>> sourceUids
14509                        = targetComponents.valueAt(i2);
14510                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14511                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14512                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14513                        Association ass = sourceProcesses.valueAt(i4);
14514                        if (dumpPackage != null) {
14515                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14516                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14517                                continue;
14518                            }
14519                        }
14520                        printedAnything = true;
14521                        pw.print("  ");
14522                        pw.print(ass.mTargetProcess);
14523                        pw.print("/");
14524                        UserHandle.formatUid(pw, ass.mTargetUid);
14525                        pw.print(" <- ");
14526                        pw.print(ass.mSourceProcess);
14527                        pw.print("/");
14528                        UserHandle.formatUid(pw, ass.mSourceUid);
14529                        pw.println();
14530                        pw.print("    via ");
14531                        pw.print(ass.mTargetComponent.flattenToShortString());
14532                        pw.println();
14533                        pw.print("    ");
14534                        long dur = ass.mTime;
14535                        if (ass.mNesting > 0) {
14536                            dur += now - ass.mStartTime;
14537                        }
14538                        TimeUtils.formatDuration(dur, pw);
14539                        pw.print(" (");
14540                        pw.print(ass.mCount);
14541                        pw.print(" times)");
14542                        pw.print("  ");
14543                        for (int i=0; i<ass.mStateTimes.length; i++) {
14544                            long amt = ass.mStateTimes[i];
14545                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14546                                amt += now - ass.mLastStateUptime;
14547                            }
14548                            if (amt != 0) {
14549                                pw.print(" ");
14550                                pw.print(ProcessList.makeProcStateString(
14551                                            i + ActivityManager.MIN_PROCESS_STATE));
14552                                pw.print("=");
14553                                TimeUtils.formatDuration(amt, pw);
14554                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14555                                    pw.print("*");
14556                                }
14557                            }
14558                        }
14559                        pw.println();
14560                        if (ass.mNesting > 0) {
14561                            pw.print("    Currently active: ");
14562                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14563                            pw.println();
14564                        }
14565                    }
14566                }
14567            }
14568
14569        }
14570
14571        if (!printedAnything) {
14572            pw.println("  (nothing)");
14573        }
14574    }
14575
14576    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14577            String header, boolean needSep) {
14578        boolean printed = false;
14579        int whichAppId = -1;
14580        if (dumpPackage != null) {
14581            try {
14582                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14583                        dumpPackage, 0);
14584                whichAppId = UserHandle.getAppId(info.uid);
14585            } catch (NameNotFoundException e) {
14586                e.printStackTrace();
14587            }
14588        }
14589        for (int i=0; i<uids.size(); i++) {
14590            UidRecord uidRec = uids.valueAt(i);
14591            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14592                continue;
14593            }
14594            if (!printed) {
14595                printed = true;
14596                if (needSep) {
14597                    pw.println();
14598                }
14599                pw.print("  ");
14600                pw.println(header);
14601                needSep = true;
14602            }
14603            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14604            pw.print(": "); pw.println(uidRec);
14605        }
14606        return printed;
14607    }
14608
14609    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14610            int opti, boolean dumpAll, String dumpPackage) {
14611        boolean needSep = false;
14612        boolean printedAnything = false;
14613        int numPers = 0;
14614
14615        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14616
14617        if (dumpAll) {
14618            final int NP = mProcessNames.getMap().size();
14619            for (int ip=0; ip<NP; ip++) {
14620                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14621                final int NA = procs.size();
14622                for (int ia=0; ia<NA; ia++) {
14623                    ProcessRecord r = procs.valueAt(ia);
14624                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14625                        continue;
14626                    }
14627                    if (!needSep) {
14628                        pw.println("  All known processes:");
14629                        needSep = true;
14630                        printedAnything = true;
14631                    }
14632                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14633                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14634                        pw.print(" "); pw.println(r);
14635                    r.dump(pw, "    ");
14636                    if (r.persistent) {
14637                        numPers++;
14638                    }
14639                }
14640            }
14641        }
14642
14643        if (mIsolatedProcesses.size() > 0) {
14644            boolean printed = false;
14645            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14646                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14647                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14648                    continue;
14649                }
14650                if (!printed) {
14651                    if (needSep) {
14652                        pw.println();
14653                    }
14654                    pw.println("  Isolated process list (sorted by uid):");
14655                    printedAnything = true;
14656                    printed = true;
14657                    needSep = true;
14658                }
14659                pw.println(String.format("%sIsolated #%2d: %s",
14660                        "    ", i, r.toString()));
14661            }
14662        }
14663
14664        if (mActiveUids.size() > 0) {
14665            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14666                printedAnything = needSep = true;
14667            }
14668        }
14669        if (mValidateUids.size() > 0) {
14670            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14671                printedAnything = needSep = true;
14672            }
14673        }
14674
14675        if (mLruProcesses.size() > 0) {
14676            if (needSep) {
14677                pw.println();
14678            }
14679            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14680                    pw.print(" total, non-act at ");
14681                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14682                    pw.print(", non-svc at ");
14683                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14684                    pw.println("):");
14685            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14686            needSep = true;
14687            printedAnything = true;
14688        }
14689
14690        if (dumpAll || dumpPackage != null) {
14691            synchronized (mPidsSelfLocked) {
14692                boolean printed = false;
14693                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14694                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14695                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14696                        continue;
14697                    }
14698                    if (!printed) {
14699                        if (needSep) pw.println();
14700                        needSep = true;
14701                        pw.println("  PID mappings:");
14702                        printed = true;
14703                        printedAnything = true;
14704                    }
14705                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14706                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14707                }
14708            }
14709        }
14710
14711        if (mForegroundProcesses.size() > 0) {
14712            synchronized (mPidsSelfLocked) {
14713                boolean printed = false;
14714                for (int i=0; i<mForegroundProcesses.size(); i++) {
14715                    ProcessRecord r = mPidsSelfLocked.get(
14716                            mForegroundProcesses.valueAt(i).pid);
14717                    if (dumpPackage != null && (r == null
14718                            || !r.pkgList.containsKey(dumpPackage))) {
14719                        continue;
14720                    }
14721                    if (!printed) {
14722                        if (needSep) pw.println();
14723                        needSep = true;
14724                        pw.println("  Foreground Processes:");
14725                        printed = true;
14726                        printedAnything = true;
14727                    }
14728                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14729                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14730                }
14731            }
14732        }
14733
14734        if (mPersistentStartingProcesses.size() > 0) {
14735            if (needSep) pw.println();
14736            needSep = true;
14737            printedAnything = true;
14738            pw.println("  Persisent processes that are starting:");
14739            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14740                    "Starting Norm", "Restarting PERS", dumpPackage);
14741        }
14742
14743        if (mRemovedProcesses.size() > 0) {
14744            if (needSep) pw.println();
14745            needSep = true;
14746            printedAnything = true;
14747            pw.println("  Processes that are being removed:");
14748            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14749                    "Removed Norm", "Removed PERS", dumpPackage);
14750        }
14751
14752        if (mProcessesOnHold.size() > 0) {
14753            if (needSep) pw.println();
14754            needSep = true;
14755            printedAnything = true;
14756            pw.println("  Processes that are on old until the system is ready:");
14757            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14758                    "OnHold Norm", "OnHold PERS", dumpPackage);
14759        }
14760
14761        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14762
14763        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14764        if (needSep) {
14765            printedAnything = true;
14766        }
14767
14768        if (dumpPackage == null) {
14769            pw.println();
14770            needSep = false;
14771            mUserController.dump(pw, dumpAll);
14772        }
14773        if (mHomeProcess != null && (dumpPackage == null
14774                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14775            if (needSep) {
14776                pw.println();
14777                needSep = false;
14778            }
14779            pw.println("  mHomeProcess: " + mHomeProcess);
14780        }
14781        if (mPreviousProcess != null && (dumpPackage == null
14782                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14783            if (needSep) {
14784                pw.println();
14785                needSep = false;
14786            }
14787            pw.println("  mPreviousProcess: " + mPreviousProcess);
14788        }
14789        if (dumpAll) {
14790            StringBuilder sb = new StringBuilder(128);
14791            sb.append("  mPreviousProcessVisibleTime: ");
14792            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14793            pw.println(sb);
14794        }
14795        if (mHeavyWeightProcess != null && (dumpPackage == null
14796                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14797            if (needSep) {
14798                pw.println();
14799                needSep = false;
14800            }
14801            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14802        }
14803        if (dumpPackage == null) {
14804            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14805            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14806        }
14807        if (dumpAll) {
14808            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14809            if (mCompatModePackages.getPackages().size() > 0) {
14810                boolean printed = false;
14811                for (Map.Entry<String, Integer> entry
14812                        : mCompatModePackages.getPackages().entrySet()) {
14813                    String pkg = entry.getKey();
14814                    int mode = entry.getValue();
14815                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14816                        continue;
14817                    }
14818                    if (!printed) {
14819                        pw.println("  mScreenCompatPackages:");
14820                        printed = true;
14821                    }
14822                    pw.print("    "); pw.print(pkg); pw.print(": ");
14823                            pw.print(mode); pw.println();
14824                }
14825            }
14826            final int NI = mUidObservers.getRegisteredCallbackCount();
14827            boolean printed = false;
14828            for (int i=0; i<NI; i++) {
14829                final UidObserverRegistration reg = (UidObserverRegistration)
14830                        mUidObservers.getRegisteredCallbackCookie(i);
14831                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
14832                    if (!printed) {
14833                        pw.println("  mUidObservers:");
14834                        printed = true;
14835                    }
14836                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
14837                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
14838                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
14839                        pw.print(" IDLE");
14840                    }
14841                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
14842                        pw.print(" ACT" );
14843                    }
14844                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
14845                        pw.print(" GONE");
14846                    }
14847                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
14848                        pw.print(" STATE");
14849                        pw.print(" (cut="); pw.print(reg.cutpoint);
14850                        pw.print(")");
14851                    }
14852                    pw.println();
14853                    if (reg.lastProcStates != null) {
14854                        final int NJ = reg.lastProcStates.size();
14855                        for (int j=0; j<NJ; j++) {
14856                            pw.print("      Last ");
14857                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
14858                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
14859                        }
14860                    }
14861                }
14862            }
14863        }
14864        if (dumpPackage == null) {
14865            pw.println("  mWakefulness="
14866                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14867            pw.println("  mSleepTokens=" + mSleepTokens);
14868            pw.println("  mSleeping=" + mSleeping);
14869            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14870            if (mRunningVoice != null) {
14871                pw.println("  mRunningVoice=" + mRunningVoice);
14872                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14873            }
14874        }
14875        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14876                || mOrigWaitForDebugger) {
14877            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14878                    || dumpPackage.equals(mOrigDebugApp)) {
14879                if (needSep) {
14880                    pw.println();
14881                    needSep = false;
14882                }
14883                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14884                        + " mDebugTransient=" + mDebugTransient
14885                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14886            }
14887        }
14888        if (mCurAppTimeTracker != null) {
14889            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14890        }
14891        if (mMemWatchProcesses.getMap().size() > 0) {
14892            pw.println("  Mem watch processes:");
14893            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14894                    = mMemWatchProcesses.getMap();
14895            for (int i=0; i<procs.size(); i++) {
14896                final String proc = procs.keyAt(i);
14897                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14898                for (int j=0; j<uids.size(); j++) {
14899                    if (needSep) {
14900                        pw.println();
14901                        needSep = false;
14902                    }
14903                    StringBuilder sb = new StringBuilder();
14904                    sb.append("    ").append(proc).append('/');
14905                    UserHandle.formatUid(sb, uids.keyAt(j));
14906                    Pair<Long, String> val = uids.valueAt(j);
14907                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14908                    if (val.second != null) {
14909                        sb.append(", report to ").append(val.second);
14910                    }
14911                    pw.println(sb.toString());
14912                }
14913            }
14914            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14915            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14916            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14917                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14918        }
14919        if (mTrackAllocationApp != null) {
14920            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14921                if (needSep) {
14922                    pw.println();
14923                    needSep = false;
14924                }
14925                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14926            }
14927        }
14928        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14929                || mProfileFd != null) {
14930            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14931                if (needSep) {
14932                    pw.println();
14933                    needSep = false;
14934                }
14935                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14936                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14937                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14938                        + mAutoStopProfiler);
14939                pw.println("  mProfileType=" + mProfileType);
14940            }
14941        }
14942        if (mNativeDebuggingApp != null) {
14943            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14944                if (needSep) {
14945                    pw.println();
14946                    needSep = false;
14947                }
14948                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14949            }
14950        }
14951        if (dumpPackage == null) {
14952            if (mAlwaysFinishActivities) {
14953                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
14954            }
14955            if (mController != null) {
14956                pw.println("  mController=" + mController
14957                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14958            }
14959            if (dumpAll) {
14960                pw.println("  Total persistent processes: " + numPers);
14961                pw.println("  mProcessesReady=" + mProcessesReady
14962                        + " mSystemReady=" + mSystemReady
14963                        + " mBooted=" + mBooted
14964                        + " mFactoryTest=" + mFactoryTest);
14965                pw.println("  mBooting=" + mBooting
14966                        + " mCallFinishBooting=" + mCallFinishBooting
14967                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14968                pw.print("  mLastPowerCheckRealtime=");
14969                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14970                        pw.println("");
14971                pw.print("  mLastPowerCheckUptime=");
14972                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14973                        pw.println("");
14974                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14975                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14976                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14977                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14978                        + " (" + mLruProcesses.size() + " total)"
14979                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14980                        + " mNumServiceProcs=" + mNumServiceProcs
14981                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14982                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14983                        + " mLastMemoryLevel=" + mLastMemoryLevel
14984                        + " mLastNumProcesses=" + mLastNumProcesses);
14985                long now = SystemClock.uptimeMillis();
14986                pw.print("  mLastIdleTime=");
14987                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14988                        pw.print(" mLowRamSinceLastIdle=");
14989                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14990                        pw.println();
14991            }
14992        }
14993
14994        if (!printedAnything) {
14995            pw.println("  (nothing)");
14996        }
14997    }
14998
14999    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15000            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15001        if (mProcessesToGc.size() > 0) {
15002            boolean printed = false;
15003            long now = SystemClock.uptimeMillis();
15004            for (int i=0; i<mProcessesToGc.size(); i++) {
15005                ProcessRecord proc = mProcessesToGc.get(i);
15006                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15007                    continue;
15008                }
15009                if (!printed) {
15010                    if (needSep) pw.println();
15011                    needSep = true;
15012                    pw.println("  Processes that are waiting to GC:");
15013                    printed = true;
15014                }
15015                pw.print("    Process "); pw.println(proc);
15016                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15017                        pw.print(", last gced=");
15018                        pw.print(now-proc.lastRequestedGc);
15019                        pw.print(" ms ago, last lowMem=");
15020                        pw.print(now-proc.lastLowMemory);
15021                        pw.println(" ms ago");
15022
15023            }
15024        }
15025        return needSep;
15026    }
15027
15028    void printOomLevel(PrintWriter pw, String name, int adj) {
15029        pw.print("    ");
15030        if (adj >= 0) {
15031            pw.print(' ');
15032            if (adj < 10) pw.print(' ');
15033        } else {
15034            if (adj > -10) pw.print(' ');
15035        }
15036        pw.print(adj);
15037        pw.print(": ");
15038        pw.print(name);
15039        pw.print(" (");
15040        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15041        pw.println(")");
15042    }
15043
15044    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15045            int opti, boolean dumpAll) {
15046        boolean needSep = false;
15047
15048        if (mLruProcesses.size() > 0) {
15049            if (needSep) pw.println();
15050            needSep = true;
15051            pw.println("  OOM levels:");
15052            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15053            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15054            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15055            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15056            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15057            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15058            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15059            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15060            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15061            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15062            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15063            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15064            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15065            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15066
15067            if (needSep) pw.println();
15068            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15069                    pw.print(" total, non-act at ");
15070                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15071                    pw.print(", non-svc at ");
15072                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15073                    pw.println("):");
15074            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15075            needSep = true;
15076        }
15077
15078        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15079
15080        pw.println();
15081        pw.println("  mHomeProcess: " + mHomeProcess);
15082        pw.println("  mPreviousProcess: " + mPreviousProcess);
15083        if (mHeavyWeightProcess != null) {
15084            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15085        }
15086
15087        return true;
15088    }
15089
15090    /**
15091     * There are three ways to call this:
15092     *  - no provider specified: dump all the providers
15093     *  - a flattened component name that matched an existing provider was specified as the
15094     *    first arg: dump that one provider
15095     *  - the first arg isn't the flattened component name of an existing provider:
15096     *    dump all providers whose component contains the first arg as a substring
15097     */
15098    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15099            int opti, boolean dumpAll) {
15100        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15101    }
15102
15103    static class ItemMatcher {
15104        ArrayList<ComponentName> components;
15105        ArrayList<String> strings;
15106        ArrayList<Integer> objects;
15107        boolean all;
15108
15109        ItemMatcher() {
15110            all = true;
15111        }
15112
15113        void build(String name) {
15114            ComponentName componentName = ComponentName.unflattenFromString(name);
15115            if (componentName != null) {
15116                if (components == null) {
15117                    components = new ArrayList<ComponentName>();
15118                }
15119                components.add(componentName);
15120                all = false;
15121            } else {
15122                int objectId = 0;
15123                // Not a '/' separated full component name; maybe an object ID?
15124                try {
15125                    objectId = Integer.parseInt(name, 16);
15126                    if (objects == null) {
15127                        objects = new ArrayList<Integer>();
15128                    }
15129                    objects.add(objectId);
15130                    all = false;
15131                } catch (RuntimeException e) {
15132                    // Not an integer; just do string match.
15133                    if (strings == null) {
15134                        strings = new ArrayList<String>();
15135                    }
15136                    strings.add(name);
15137                    all = false;
15138                }
15139            }
15140        }
15141
15142        int build(String[] args, int opti) {
15143            for (; opti<args.length; opti++) {
15144                String name = args[opti];
15145                if ("--".equals(name)) {
15146                    return opti+1;
15147                }
15148                build(name);
15149            }
15150            return opti;
15151        }
15152
15153        boolean match(Object object, ComponentName comp) {
15154            if (all) {
15155                return true;
15156            }
15157            if (components != null) {
15158                for (int i=0; i<components.size(); i++) {
15159                    if (components.get(i).equals(comp)) {
15160                        return true;
15161                    }
15162                }
15163            }
15164            if (objects != null) {
15165                for (int i=0; i<objects.size(); i++) {
15166                    if (System.identityHashCode(object) == objects.get(i)) {
15167                        return true;
15168                    }
15169                }
15170            }
15171            if (strings != null) {
15172                String flat = comp.flattenToString();
15173                for (int i=0; i<strings.size(); i++) {
15174                    if (flat.contains(strings.get(i))) {
15175                        return true;
15176                    }
15177                }
15178            }
15179            return false;
15180        }
15181    }
15182
15183    /**
15184     * There are three things that cmd can be:
15185     *  - a flattened component name that matches an existing activity
15186     *  - the cmd arg isn't the flattened component name of an existing activity:
15187     *    dump all activity whose component contains the cmd as a substring
15188     *  - A hex number of the ActivityRecord object instance.
15189     */
15190    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15191            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15192        ArrayList<ActivityRecord> activities;
15193
15194        synchronized (this) {
15195            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15196        }
15197
15198        if (activities.size() <= 0) {
15199            return false;
15200        }
15201
15202        String[] newArgs = new String[args.length - opti];
15203        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15204
15205        TaskRecord lastTask = null;
15206        boolean needSep = false;
15207        for (int i=activities.size()-1; i>=0; i--) {
15208            ActivityRecord r = activities.get(i);
15209            if (needSep) {
15210                pw.println();
15211            }
15212            needSep = true;
15213            synchronized (this) {
15214                if (lastTask != r.task) {
15215                    lastTask = r.task;
15216                    pw.print("TASK "); pw.print(lastTask.affinity);
15217                            pw.print(" id="); pw.print(lastTask.taskId);
15218                            pw.print(" userId="); pw.println(lastTask.userId);
15219                    if (dumpAll) {
15220                        lastTask.dump(pw, "  ");
15221                    }
15222                }
15223            }
15224            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15225        }
15226        return true;
15227    }
15228
15229    /**
15230     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15231     * there is a thread associated with the activity.
15232     */
15233    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15234            final ActivityRecord r, String[] args, boolean dumpAll) {
15235        String innerPrefix = prefix + "  ";
15236        synchronized (this) {
15237            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15238                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15239                    pw.print(" pid=");
15240                    if (r.app != null) pw.println(r.app.pid);
15241                    else pw.println("(not running)");
15242            if (dumpAll) {
15243                r.dump(pw, innerPrefix);
15244            }
15245        }
15246        if (r.app != null && r.app.thread != null) {
15247            // flush anything that is already in the PrintWriter since the thread is going
15248            // to write to the file descriptor directly
15249            pw.flush();
15250            try {
15251                TransferPipe tp = new TransferPipe();
15252                try {
15253                    r.app.thread.dumpActivity(tp.getWriteFd(),
15254                            r.appToken, innerPrefix, args);
15255                    tp.go(fd);
15256                } finally {
15257                    tp.kill();
15258                }
15259            } catch (IOException e) {
15260                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15261            } catch (RemoteException e) {
15262                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15263            }
15264        }
15265    }
15266
15267    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15268            int opti, boolean dumpAll, String dumpPackage) {
15269        boolean needSep = false;
15270        boolean onlyHistory = false;
15271        boolean printedAnything = false;
15272
15273        if ("history".equals(dumpPackage)) {
15274            if (opti < args.length && "-s".equals(args[opti])) {
15275                dumpAll = false;
15276            }
15277            onlyHistory = true;
15278            dumpPackage = null;
15279        }
15280
15281        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15282        if (!onlyHistory && dumpAll) {
15283            if (mRegisteredReceivers.size() > 0) {
15284                boolean printed = false;
15285                Iterator it = mRegisteredReceivers.values().iterator();
15286                while (it.hasNext()) {
15287                    ReceiverList r = (ReceiverList)it.next();
15288                    if (dumpPackage != null && (r.app == null ||
15289                            !dumpPackage.equals(r.app.info.packageName))) {
15290                        continue;
15291                    }
15292                    if (!printed) {
15293                        pw.println("  Registered Receivers:");
15294                        needSep = true;
15295                        printed = true;
15296                        printedAnything = true;
15297                    }
15298                    pw.print("  * "); pw.println(r);
15299                    r.dump(pw, "    ");
15300                }
15301            }
15302
15303            if (mReceiverResolver.dump(pw, needSep ?
15304                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15305                    "    ", dumpPackage, false, false)) {
15306                needSep = true;
15307                printedAnything = true;
15308            }
15309        }
15310
15311        for (BroadcastQueue q : mBroadcastQueues) {
15312            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15313            printedAnything |= needSep;
15314        }
15315
15316        needSep = true;
15317
15318        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15319            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15320                if (needSep) {
15321                    pw.println();
15322                }
15323                needSep = true;
15324                printedAnything = true;
15325                pw.print("  Sticky broadcasts for user ");
15326                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15327                StringBuilder sb = new StringBuilder(128);
15328                for (Map.Entry<String, ArrayList<Intent>> ent
15329                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15330                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15331                    if (dumpAll) {
15332                        pw.println(":");
15333                        ArrayList<Intent> intents = ent.getValue();
15334                        final int N = intents.size();
15335                        for (int i=0; i<N; i++) {
15336                            sb.setLength(0);
15337                            sb.append("    Intent: ");
15338                            intents.get(i).toShortString(sb, false, true, false, false);
15339                            pw.println(sb.toString());
15340                            Bundle bundle = intents.get(i).getExtras();
15341                            if (bundle != null) {
15342                                pw.print("      ");
15343                                pw.println(bundle.toString());
15344                            }
15345                        }
15346                    } else {
15347                        pw.println("");
15348                    }
15349                }
15350            }
15351        }
15352
15353        if (!onlyHistory && dumpAll) {
15354            pw.println();
15355            for (BroadcastQueue queue : mBroadcastQueues) {
15356                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15357                        + queue.mBroadcastsScheduled);
15358            }
15359            pw.println("  mHandler:");
15360            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15361            needSep = true;
15362            printedAnything = true;
15363        }
15364
15365        if (!printedAnything) {
15366            pw.println("  (nothing)");
15367        }
15368    }
15369
15370    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15371            int opti, boolean dumpAll, String dumpPackage) {
15372        if (mCurBroadcastStats == null) {
15373            return;
15374        }
15375
15376        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15377        final long now = SystemClock.elapsedRealtime();
15378        if (mLastBroadcastStats != null) {
15379            pw.print("  Last stats (from ");
15380            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15381            pw.print(" to ");
15382            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15383            pw.print(", ");
15384            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15385                    - mLastBroadcastStats.mStartUptime, pw);
15386            pw.println(" uptime):");
15387            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15388                pw.println("    (nothing)");
15389            }
15390            pw.println();
15391        }
15392        pw.print("  Current stats (from ");
15393        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15394        pw.print(" to now, ");
15395        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15396                - mCurBroadcastStats.mStartUptime, pw);
15397        pw.println(" uptime):");
15398        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15399            pw.println("    (nothing)");
15400        }
15401    }
15402
15403    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15404            int opti, boolean fullCheckin, String dumpPackage) {
15405        if (mCurBroadcastStats == null) {
15406            return;
15407        }
15408
15409        if (mLastBroadcastStats != null) {
15410            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15411            if (fullCheckin) {
15412                mLastBroadcastStats = null;
15413                return;
15414            }
15415        }
15416        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15417        if (fullCheckin) {
15418            mCurBroadcastStats = null;
15419        }
15420    }
15421
15422    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15423            int opti, boolean dumpAll, String dumpPackage) {
15424        boolean needSep;
15425        boolean printedAnything = false;
15426
15427        ItemMatcher matcher = new ItemMatcher();
15428        matcher.build(args, opti);
15429
15430        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15431
15432        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15433        printedAnything |= needSep;
15434
15435        if (mLaunchingProviders.size() > 0) {
15436            boolean printed = false;
15437            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15438                ContentProviderRecord r = mLaunchingProviders.get(i);
15439                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15440                    continue;
15441                }
15442                if (!printed) {
15443                    if (needSep) pw.println();
15444                    needSep = true;
15445                    pw.println("  Launching content providers:");
15446                    printed = true;
15447                    printedAnything = true;
15448                }
15449                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15450                        pw.println(r);
15451            }
15452        }
15453
15454        if (!printedAnything) {
15455            pw.println("  (nothing)");
15456        }
15457    }
15458
15459    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15460            int opti, boolean dumpAll, String dumpPackage) {
15461        boolean needSep = false;
15462        boolean printedAnything = false;
15463
15464        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15465
15466        if (mGrantedUriPermissions.size() > 0) {
15467            boolean printed = false;
15468            int dumpUid = -2;
15469            if (dumpPackage != null) {
15470                try {
15471                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15472                            MATCH_ANY_USER, 0);
15473                } catch (NameNotFoundException e) {
15474                    dumpUid = -1;
15475                }
15476            }
15477            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15478                int uid = mGrantedUriPermissions.keyAt(i);
15479                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15480                    continue;
15481                }
15482                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15483                if (!printed) {
15484                    if (needSep) pw.println();
15485                    needSep = true;
15486                    pw.println("  Granted Uri Permissions:");
15487                    printed = true;
15488                    printedAnything = true;
15489                }
15490                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15491                for (UriPermission perm : perms.values()) {
15492                    pw.print("    "); pw.println(perm);
15493                    if (dumpAll) {
15494                        perm.dump(pw, "      ");
15495                    }
15496                }
15497            }
15498        }
15499
15500        if (!printedAnything) {
15501            pw.println("  (nothing)");
15502        }
15503    }
15504
15505    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15506            int opti, boolean dumpAll, String dumpPackage) {
15507        boolean printed = false;
15508
15509        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15510
15511        if (mIntentSenderRecords.size() > 0) {
15512            Iterator<WeakReference<PendingIntentRecord>> it
15513                    = mIntentSenderRecords.values().iterator();
15514            while (it.hasNext()) {
15515                WeakReference<PendingIntentRecord> ref = it.next();
15516                PendingIntentRecord rec = ref != null ? ref.get(): null;
15517                if (dumpPackage != null && (rec == null
15518                        || !dumpPackage.equals(rec.key.packageName))) {
15519                    continue;
15520                }
15521                printed = true;
15522                if (rec != null) {
15523                    pw.print("  * "); pw.println(rec);
15524                    if (dumpAll) {
15525                        rec.dump(pw, "    ");
15526                    }
15527                } else {
15528                    pw.print("  * "); pw.println(ref);
15529                }
15530            }
15531        }
15532
15533        if (!printed) {
15534            pw.println("  (nothing)");
15535        }
15536    }
15537
15538    private static final int dumpProcessList(PrintWriter pw,
15539            ActivityManagerService service, List list,
15540            String prefix, String normalLabel, String persistentLabel,
15541            String dumpPackage) {
15542        int numPers = 0;
15543        final int N = list.size()-1;
15544        for (int i=N; i>=0; i--) {
15545            ProcessRecord r = (ProcessRecord)list.get(i);
15546            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15547                continue;
15548            }
15549            pw.println(String.format("%s%s #%2d: %s",
15550                    prefix, (r.persistent ? persistentLabel : normalLabel),
15551                    i, r.toString()));
15552            if (r.persistent) {
15553                numPers++;
15554            }
15555        }
15556        return numPers;
15557    }
15558
15559    private static final boolean dumpProcessOomList(PrintWriter pw,
15560            ActivityManagerService service, List<ProcessRecord> origList,
15561            String prefix, String normalLabel, String persistentLabel,
15562            boolean inclDetails, String dumpPackage) {
15563
15564        ArrayList<Pair<ProcessRecord, Integer>> list
15565                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15566        for (int i=0; i<origList.size(); i++) {
15567            ProcessRecord r = origList.get(i);
15568            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15569                continue;
15570            }
15571            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15572        }
15573
15574        if (list.size() <= 0) {
15575            return false;
15576        }
15577
15578        Comparator<Pair<ProcessRecord, Integer>> comparator
15579                = new Comparator<Pair<ProcessRecord, Integer>>() {
15580            @Override
15581            public int compare(Pair<ProcessRecord, Integer> object1,
15582                    Pair<ProcessRecord, Integer> object2) {
15583                if (object1.first.setAdj != object2.first.setAdj) {
15584                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15585                }
15586                if (object1.first.setProcState != object2.first.setProcState) {
15587                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15588                }
15589                if (object1.second.intValue() != object2.second.intValue()) {
15590                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15591                }
15592                return 0;
15593            }
15594        };
15595
15596        Collections.sort(list, comparator);
15597
15598        final long curRealtime = SystemClock.elapsedRealtime();
15599        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15600        final long curUptime = SystemClock.uptimeMillis();
15601        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15602
15603        for (int i=list.size()-1; i>=0; i--) {
15604            ProcessRecord r = list.get(i).first;
15605            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15606            char schedGroup;
15607            switch (r.setSchedGroup) {
15608                case ProcessList.SCHED_GROUP_BACKGROUND:
15609                    schedGroup = 'B';
15610                    break;
15611                case ProcessList.SCHED_GROUP_DEFAULT:
15612                    schedGroup = 'F';
15613                    break;
15614                case ProcessList.SCHED_GROUP_TOP_APP:
15615                    schedGroup = 'T';
15616                    break;
15617                default:
15618                    schedGroup = '?';
15619                    break;
15620            }
15621            char foreground;
15622            if (r.foregroundActivities) {
15623                foreground = 'A';
15624            } else if (r.foregroundServices) {
15625                foreground = 'S';
15626            } else {
15627                foreground = ' ';
15628            }
15629            String procState = ProcessList.makeProcStateString(r.curProcState);
15630            pw.print(prefix);
15631            pw.print(r.persistent ? persistentLabel : normalLabel);
15632            pw.print(" #");
15633            int num = (origList.size()-1)-list.get(i).second;
15634            if (num < 10) pw.print(' ');
15635            pw.print(num);
15636            pw.print(": ");
15637            pw.print(oomAdj);
15638            pw.print(' ');
15639            pw.print(schedGroup);
15640            pw.print('/');
15641            pw.print(foreground);
15642            pw.print('/');
15643            pw.print(procState);
15644            pw.print(" trm:");
15645            if (r.trimMemoryLevel < 10) pw.print(' ');
15646            pw.print(r.trimMemoryLevel);
15647            pw.print(' ');
15648            pw.print(r.toShortString());
15649            pw.print(" (");
15650            pw.print(r.adjType);
15651            pw.println(')');
15652            if (r.adjSource != null || r.adjTarget != null) {
15653                pw.print(prefix);
15654                pw.print("    ");
15655                if (r.adjTarget instanceof ComponentName) {
15656                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15657                } else if (r.adjTarget != null) {
15658                    pw.print(r.adjTarget.toString());
15659                } else {
15660                    pw.print("{null}");
15661                }
15662                pw.print("<=");
15663                if (r.adjSource instanceof ProcessRecord) {
15664                    pw.print("Proc{");
15665                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15666                    pw.println("}");
15667                } else if (r.adjSource != null) {
15668                    pw.println(r.adjSource.toString());
15669                } else {
15670                    pw.println("{null}");
15671                }
15672            }
15673            if (inclDetails) {
15674                pw.print(prefix);
15675                pw.print("    ");
15676                pw.print("oom: max="); pw.print(r.maxAdj);
15677                pw.print(" curRaw="); pw.print(r.curRawAdj);
15678                pw.print(" setRaw="); pw.print(r.setRawAdj);
15679                pw.print(" cur="); pw.print(r.curAdj);
15680                pw.print(" set="); pw.println(r.setAdj);
15681                pw.print(prefix);
15682                pw.print("    ");
15683                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15684                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15685                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15686                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15687                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15688                pw.println();
15689                pw.print(prefix);
15690                pw.print("    ");
15691                pw.print("cached="); pw.print(r.cached);
15692                pw.print(" empty="); pw.print(r.empty);
15693                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15694
15695                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15696                    if (r.lastWakeTime != 0) {
15697                        long wtime;
15698                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15699                        synchronized (stats) {
15700                            wtime = stats.getProcessWakeTime(r.info.uid,
15701                                    r.pid, curRealtime);
15702                        }
15703                        long timeUsed = wtime - r.lastWakeTime;
15704                        pw.print(prefix);
15705                        pw.print("    ");
15706                        pw.print("keep awake over ");
15707                        TimeUtils.formatDuration(realtimeSince, pw);
15708                        pw.print(" used ");
15709                        TimeUtils.formatDuration(timeUsed, pw);
15710                        pw.print(" (");
15711                        pw.print((timeUsed*100)/realtimeSince);
15712                        pw.println("%)");
15713                    }
15714                    if (r.lastCpuTime != 0) {
15715                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15716                        pw.print(prefix);
15717                        pw.print("    ");
15718                        pw.print("run cpu over ");
15719                        TimeUtils.formatDuration(uptimeSince, pw);
15720                        pw.print(" used ");
15721                        TimeUtils.formatDuration(timeUsed, pw);
15722                        pw.print(" (");
15723                        pw.print((timeUsed*100)/uptimeSince);
15724                        pw.println("%)");
15725                    }
15726                }
15727            }
15728        }
15729        return true;
15730    }
15731
15732    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15733            String[] args) {
15734        ArrayList<ProcessRecord> procs;
15735        synchronized (this) {
15736            if (args != null && args.length > start
15737                    && args[start].charAt(0) != '-') {
15738                procs = new ArrayList<ProcessRecord>();
15739                int pid = -1;
15740                try {
15741                    pid = Integer.parseInt(args[start]);
15742                } catch (NumberFormatException e) {
15743                }
15744                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15745                    ProcessRecord proc = mLruProcesses.get(i);
15746                    if (proc.pid == pid) {
15747                        procs.add(proc);
15748                    } else if (allPkgs && proc.pkgList != null
15749                            && proc.pkgList.containsKey(args[start])) {
15750                        procs.add(proc);
15751                    } else if (proc.processName.equals(args[start])) {
15752                        procs.add(proc);
15753                    }
15754                }
15755                if (procs.size() <= 0) {
15756                    return null;
15757                }
15758            } else {
15759                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15760            }
15761        }
15762        return procs;
15763    }
15764
15765    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15766            PrintWriter pw, String[] args) {
15767        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15768        if (procs == null) {
15769            pw.println("No process found for: " + args[0]);
15770            return;
15771        }
15772
15773        long uptime = SystemClock.uptimeMillis();
15774        long realtime = SystemClock.elapsedRealtime();
15775        pw.println("Applications Graphics Acceleration Info:");
15776        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15777
15778        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15779            ProcessRecord r = procs.get(i);
15780            if (r.thread != null) {
15781                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15782                pw.flush();
15783                try {
15784                    TransferPipe tp = new TransferPipe();
15785                    try {
15786                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15787                        tp.go(fd);
15788                    } finally {
15789                        tp.kill();
15790                    }
15791                } catch (IOException e) {
15792                    pw.println("Failure while dumping the app: " + r);
15793                    pw.flush();
15794                } catch (RemoteException e) {
15795                    pw.println("Got a RemoteException while dumping the app " + r);
15796                    pw.flush();
15797                }
15798            }
15799        }
15800    }
15801
15802    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15803        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15804        if (procs == null) {
15805            pw.println("No process found for: " + args[0]);
15806            return;
15807        }
15808
15809        pw.println("Applications Database Info:");
15810
15811        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15812            ProcessRecord r = procs.get(i);
15813            if (r.thread != null) {
15814                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15815                pw.flush();
15816                try {
15817                    TransferPipe tp = new TransferPipe();
15818                    try {
15819                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15820                        tp.go(fd);
15821                    } finally {
15822                        tp.kill();
15823                    }
15824                } catch (IOException e) {
15825                    pw.println("Failure while dumping the app: " + r);
15826                    pw.flush();
15827                } catch (RemoteException e) {
15828                    pw.println("Got a RemoteException while dumping the app " + r);
15829                    pw.flush();
15830                }
15831            }
15832        }
15833    }
15834
15835    final static class MemItem {
15836        final boolean isProc;
15837        final String label;
15838        final String shortLabel;
15839        final long pss;
15840        final long swapPss;
15841        final int id;
15842        final boolean hasActivities;
15843        ArrayList<MemItem> subitems;
15844
15845        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15846                boolean _hasActivities) {
15847            isProc = true;
15848            label = _label;
15849            shortLabel = _shortLabel;
15850            pss = _pss;
15851            swapPss = _swapPss;
15852            id = _id;
15853            hasActivities = _hasActivities;
15854        }
15855
15856        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15857            isProc = false;
15858            label = _label;
15859            shortLabel = _shortLabel;
15860            pss = _pss;
15861            swapPss = _swapPss;
15862            id = _id;
15863            hasActivities = false;
15864        }
15865    }
15866
15867    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15868            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15869        if (sort && !isCompact) {
15870            Collections.sort(items, new Comparator<MemItem>() {
15871                @Override
15872                public int compare(MemItem lhs, MemItem rhs) {
15873                    if (lhs.pss < rhs.pss) {
15874                        return 1;
15875                    } else if (lhs.pss > rhs.pss) {
15876                        return -1;
15877                    }
15878                    return 0;
15879                }
15880            });
15881        }
15882
15883        for (int i=0; i<items.size(); i++) {
15884            MemItem mi = items.get(i);
15885            if (!isCompact) {
15886                if (dumpSwapPss) {
15887                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15888                            mi.label, stringifyKBSize(mi.swapPss));
15889                } else {
15890                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15891                }
15892            } else if (mi.isProc) {
15893                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15894                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15895                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15896                pw.println(mi.hasActivities ? ",a" : ",e");
15897            } else {
15898                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15899                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15900            }
15901            if (mi.subitems != null) {
15902                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15903                        true, isCompact, dumpSwapPss);
15904            }
15905        }
15906    }
15907
15908    // These are in KB.
15909    static final long[] DUMP_MEM_BUCKETS = new long[] {
15910        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15911        120*1024, 160*1024, 200*1024,
15912        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15913        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15914    };
15915
15916    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15917            boolean stackLike) {
15918        int start = label.lastIndexOf('.');
15919        if (start >= 0) start++;
15920        else start = 0;
15921        int end = label.length();
15922        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15923            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15924                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15925                out.append(bucket);
15926                out.append(stackLike ? "MB." : "MB ");
15927                out.append(label, start, end);
15928                return;
15929            }
15930        }
15931        out.append(memKB/1024);
15932        out.append(stackLike ? "MB." : "MB ");
15933        out.append(label, start, end);
15934    }
15935
15936    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15937            ProcessList.NATIVE_ADJ,
15938            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15939            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15940            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15941            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15942            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15943            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15944    };
15945    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15946            "Native",
15947            "System", "Persistent", "Persistent Service", "Foreground",
15948            "Visible", "Perceptible",
15949            "Heavy Weight", "Backup",
15950            "A Services", "Home",
15951            "Previous", "B Services", "Cached"
15952    };
15953    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15954            "native",
15955            "sys", "pers", "persvc", "fore",
15956            "vis", "percept",
15957            "heavy", "backup",
15958            "servicea", "home",
15959            "prev", "serviceb", "cached"
15960    };
15961
15962    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15963            long realtime, boolean isCheckinRequest, boolean isCompact) {
15964        if (isCompact) {
15965            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15966        }
15967        if (isCheckinRequest || isCompact) {
15968            // short checkin version
15969            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15970        } else {
15971            pw.println("Applications Memory Usage (in Kilobytes):");
15972            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15973        }
15974    }
15975
15976    private static final int KSM_SHARED = 0;
15977    private static final int KSM_SHARING = 1;
15978    private static final int KSM_UNSHARED = 2;
15979    private static final int KSM_VOLATILE = 3;
15980
15981    private final long[] getKsmInfo() {
15982        long[] longOut = new long[4];
15983        final int[] SINGLE_LONG_FORMAT = new int[] {
15984            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15985        };
15986        long[] longTmp = new long[1];
15987        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15988                SINGLE_LONG_FORMAT, null, longTmp, null);
15989        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15990        longTmp[0] = 0;
15991        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15992                SINGLE_LONG_FORMAT, null, longTmp, null);
15993        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15994        longTmp[0] = 0;
15995        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15996                SINGLE_LONG_FORMAT, null, longTmp, null);
15997        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15998        longTmp[0] = 0;
15999        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16000                SINGLE_LONG_FORMAT, null, longTmp, null);
16001        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16002        return longOut;
16003    }
16004
16005    private static String stringifySize(long size, int order) {
16006        Locale locale = Locale.US;
16007        switch (order) {
16008            case 1:
16009                return String.format(locale, "%,13d", size);
16010            case 1024:
16011                return String.format(locale, "%,9dK", size / 1024);
16012            case 1024 * 1024:
16013                return String.format(locale, "%,5dM", size / 1024 / 1024);
16014            case 1024 * 1024 * 1024:
16015                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16016            default:
16017                throw new IllegalArgumentException("Invalid size order");
16018        }
16019    }
16020
16021    private static String stringifyKBSize(long size) {
16022        return stringifySize(size * 1024, 1024);
16023    }
16024
16025    // Update this version number in case you change the 'compact' format
16026    private static final int MEMINFO_COMPACT_VERSION = 1;
16027
16028    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16029            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16030        boolean dumpDetails = false;
16031        boolean dumpFullDetails = false;
16032        boolean dumpDalvik = false;
16033        boolean dumpSummaryOnly = false;
16034        boolean dumpUnreachable = false;
16035        boolean oomOnly = false;
16036        boolean isCompact = false;
16037        boolean localOnly = false;
16038        boolean packages = false;
16039        boolean isCheckinRequest = false;
16040        boolean dumpSwapPss = false;
16041
16042        int opti = 0;
16043        while (opti < args.length) {
16044            String opt = args[opti];
16045            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16046                break;
16047            }
16048            opti++;
16049            if ("-a".equals(opt)) {
16050                dumpDetails = true;
16051                dumpFullDetails = true;
16052                dumpDalvik = true;
16053                dumpSwapPss = true;
16054            } else if ("-d".equals(opt)) {
16055                dumpDalvik = true;
16056            } else if ("-c".equals(opt)) {
16057                isCompact = true;
16058            } else if ("-s".equals(opt)) {
16059                dumpDetails = true;
16060                dumpSummaryOnly = true;
16061            } else if ("-S".equals(opt)) {
16062                dumpSwapPss = true;
16063            } else if ("--unreachable".equals(opt)) {
16064                dumpUnreachable = true;
16065            } else if ("--oom".equals(opt)) {
16066                oomOnly = true;
16067            } else if ("--local".equals(opt)) {
16068                localOnly = true;
16069            } else if ("--package".equals(opt)) {
16070                packages = true;
16071            } else if ("--checkin".equals(opt)) {
16072                isCheckinRequest = true;
16073
16074            } else if ("-h".equals(opt)) {
16075                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16076                pw.println("  -a: include all available information for each process.");
16077                pw.println("  -d: include dalvik details.");
16078                pw.println("  -c: dump in a compact machine-parseable representation.");
16079                pw.println("  -s: dump only summary of application memory usage.");
16080                pw.println("  -S: dump also SwapPss.");
16081                pw.println("  --oom: only show processes organized by oom adj.");
16082                pw.println("  --local: only collect details locally, don't call process.");
16083                pw.println("  --package: interpret process arg as package, dumping all");
16084                pw.println("             processes that have loaded that package.");
16085                pw.println("  --checkin: dump data for a checkin");
16086                pw.println("If [process] is specified it can be the name or ");
16087                pw.println("pid of a specific process to dump.");
16088                return;
16089            } else {
16090                pw.println("Unknown argument: " + opt + "; use -h for help");
16091            }
16092        }
16093
16094        long uptime = SystemClock.uptimeMillis();
16095        long realtime = SystemClock.elapsedRealtime();
16096        final long[] tmpLong = new long[1];
16097
16098        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16099        if (procs == null) {
16100            // No Java processes.  Maybe they want to print a native process.
16101            if (args != null && args.length > opti
16102                    && args[opti].charAt(0) != '-') {
16103                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16104                        = new ArrayList<ProcessCpuTracker.Stats>();
16105                updateCpuStatsNow();
16106                int findPid = -1;
16107                try {
16108                    findPid = Integer.parseInt(args[opti]);
16109                } catch (NumberFormatException e) {
16110                }
16111                synchronized (mProcessCpuTracker) {
16112                    final int N = mProcessCpuTracker.countStats();
16113                    for (int i=0; i<N; i++) {
16114                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16115                        if (st.pid == findPid || (st.baseName != null
16116                                && st.baseName.equals(args[opti]))) {
16117                            nativeProcs.add(st);
16118                        }
16119                    }
16120                }
16121                if (nativeProcs.size() > 0) {
16122                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16123                            isCompact);
16124                    Debug.MemoryInfo mi = null;
16125                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16126                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16127                        final int pid = r.pid;
16128                        if (!isCheckinRequest && dumpDetails) {
16129                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16130                        }
16131                        if (mi == null) {
16132                            mi = new Debug.MemoryInfo();
16133                        }
16134                        if (dumpDetails || (!brief && !oomOnly)) {
16135                            Debug.getMemoryInfo(pid, mi);
16136                        } else {
16137                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16138                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16139                        }
16140                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16141                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16142                        if (isCheckinRequest) {
16143                            pw.println();
16144                        }
16145                    }
16146                    return;
16147                }
16148            }
16149            pw.println("No process found for: " + args[opti]);
16150            return;
16151        }
16152
16153        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16154            dumpDetails = true;
16155        }
16156
16157        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16158
16159        String[] innerArgs = new String[args.length-opti];
16160        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16161
16162        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16163        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16164        long nativePss = 0;
16165        long nativeSwapPss = 0;
16166        long dalvikPss = 0;
16167        long dalvikSwapPss = 0;
16168        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16169                EmptyArray.LONG;
16170        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16171                EmptyArray.LONG;
16172        long otherPss = 0;
16173        long otherSwapPss = 0;
16174        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16175        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16176
16177        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16178        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16179        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16180                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16181
16182        long totalPss = 0;
16183        long totalSwapPss = 0;
16184        long cachedPss = 0;
16185        long cachedSwapPss = 0;
16186        boolean hasSwapPss = false;
16187
16188        Debug.MemoryInfo mi = null;
16189        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16190            final ProcessRecord r = procs.get(i);
16191            final IApplicationThread thread;
16192            final int pid;
16193            final int oomAdj;
16194            final boolean hasActivities;
16195            synchronized (this) {
16196                thread = r.thread;
16197                pid = r.pid;
16198                oomAdj = r.getSetAdjWithServices();
16199                hasActivities = r.activities.size() > 0;
16200            }
16201            if (thread != null) {
16202                if (!isCheckinRequest && dumpDetails) {
16203                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16204                }
16205                if (mi == null) {
16206                    mi = new Debug.MemoryInfo();
16207                }
16208                if (dumpDetails || (!brief && !oomOnly)) {
16209                    Debug.getMemoryInfo(pid, mi);
16210                    hasSwapPss = mi.hasSwappedOutPss;
16211                } else {
16212                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16213                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16214                }
16215                if (dumpDetails) {
16216                    if (localOnly) {
16217                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16218                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16219                        if (isCheckinRequest) {
16220                            pw.println();
16221                        }
16222                    } else {
16223                        pw.flush();
16224                        try {
16225                            TransferPipe tp = new TransferPipe();
16226                            try {
16227                                thread.dumpMemInfo(tp.getWriteFd(),
16228                                        mi, isCheckinRequest, dumpFullDetails,
16229                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16230                                tp.go(fd);
16231                            } finally {
16232                                tp.kill();
16233                            }
16234                        } catch (IOException e) {
16235                            if (!isCheckinRequest) {
16236                                pw.println("Got IoException!");
16237                                pw.flush();
16238                            }
16239                        } catch (RemoteException e) {
16240                            if (!isCheckinRequest) {
16241                                pw.println("Got RemoteException!");
16242                                pw.flush();
16243                            }
16244                        }
16245                    }
16246                }
16247
16248                final long myTotalPss = mi.getTotalPss();
16249                final long myTotalUss = mi.getTotalUss();
16250                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16251
16252                synchronized (this) {
16253                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16254                        // Record this for posterity if the process has been stable.
16255                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16256                    }
16257                }
16258
16259                if (!isCheckinRequest && mi != null) {
16260                    totalPss += myTotalPss;
16261                    totalSwapPss += myTotalSwapPss;
16262                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16263                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16264                            myTotalSwapPss, pid, hasActivities);
16265                    procMems.add(pssItem);
16266                    procMemsMap.put(pid, pssItem);
16267
16268                    nativePss += mi.nativePss;
16269                    nativeSwapPss += mi.nativeSwappedOutPss;
16270                    dalvikPss += mi.dalvikPss;
16271                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16272                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16273                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16274                        dalvikSubitemSwapPss[j] +=
16275                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16276                    }
16277                    otherPss += mi.otherPss;
16278                    otherSwapPss += mi.otherSwappedOutPss;
16279                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16280                        long mem = mi.getOtherPss(j);
16281                        miscPss[j] += mem;
16282                        otherPss -= mem;
16283                        mem = mi.getOtherSwappedOutPss(j);
16284                        miscSwapPss[j] += mem;
16285                        otherSwapPss -= mem;
16286                    }
16287
16288                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16289                        cachedPss += myTotalPss;
16290                        cachedSwapPss += myTotalSwapPss;
16291                    }
16292
16293                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16294                        if (oomIndex == (oomPss.length - 1)
16295                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16296                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16297                            oomPss[oomIndex] += myTotalPss;
16298                            oomSwapPss[oomIndex] += myTotalSwapPss;
16299                            if (oomProcs[oomIndex] == null) {
16300                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16301                            }
16302                            oomProcs[oomIndex].add(pssItem);
16303                            break;
16304                        }
16305                    }
16306                }
16307            }
16308        }
16309
16310        long nativeProcTotalPss = 0;
16311
16312        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16313            // If we are showing aggregations, also look for native processes to
16314            // include so that our aggregations are more accurate.
16315            updateCpuStatsNow();
16316            mi = null;
16317            synchronized (mProcessCpuTracker) {
16318                final int N = mProcessCpuTracker.countStats();
16319                for (int i=0; i<N; i++) {
16320                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16321                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16322                        if (mi == null) {
16323                            mi = new Debug.MemoryInfo();
16324                        }
16325                        if (!brief && !oomOnly) {
16326                            Debug.getMemoryInfo(st.pid, mi);
16327                        } else {
16328                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16329                            mi.nativePrivateDirty = (int)tmpLong[0];
16330                        }
16331
16332                        final long myTotalPss = mi.getTotalPss();
16333                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16334                        totalPss += myTotalPss;
16335                        nativeProcTotalPss += myTotalPss;
16336
16337                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16338                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16339                        procMems.add(pssItem);
16340
16341                        nativePss += mi.nativePss;
16342                        nativeSwapPss += mi.nativeSwappedOutPss;
16343                        dalvikPss += mi.dalvikPss;
16344                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16345                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16346                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16347                            dalvikSubitemSwapPss[j] +=
16348                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16349                        }
16350                        otherPss += mi.otherPss;
16351                        otherSwapPss += mi.otherSwappedOutPss;
16352                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16353                            long mem = mi.getOtherPss(j);
16354                            miscPss[j] += mem;
16355                            otherPss -= mem;
16356                            mem = mi.getOtherSwappedOutPss(j);
16357                            miscSwapPss[j] += mem;
16358                            otherSwapPss -= mem;
16359                        }
16360                        oomPss[0] += myTotalPss;
16361                        oomSwapPss[0] += myTotalSwapPss;
16362                        if (oomProcs[0] == null) {
16363                            oomProcs[0] = new ArrayList<MemItem>();
16364                        }
16365                        oomProcs[0].add(pssItem);
16366                    }
16367                }
16368            }
16369
16370            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16371
16372            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16373            final MemItem dalvikItem =
16374                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16375            if (dalvikSubitemPss.length > 0) {
16376                dalvikItem.subitems = new ArrayList<MemItem>();
16377                for (int j=0; j<dalvikSubitemPss.length; j++) {
16378                    final String name = Debug.MemoryInfo.getOtherLabel(
16379                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16380                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16381                                    dalvikSubitemSwapPss[j], j));
16382                }
16383            }
16384            catMems.add(dalvikItem);
16385            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16386            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16387                String label = Debug.MemoryInfo.getOtherLabel(j);
16388                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16389            }
16390
16391            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16392            for (int j=0; j<oomPss.length; j++) {
16393                if (oomPss[j] != 0) {
16394                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16395                            : DUMP_MEM_OOM_LABEL[j];
16396                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16397                            DUMP_MEM_OOM_ADJ[j]);
16398                    item.subitems = oomProcs[j];
16399                    oomMems.add(item);
16400                }
16401            }
16402
16403            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16404            if (!brief && !oomOnly && !isCompact) {
16405                pw.println();
16406                pw.println("Total PSS by process:");
16407                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16408                pw.println();
16409            }
16410            if (!isCompact) {
16411                pw.println("Total PSS by OOM adjustment:");
16412            }
16413            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16414            if (!brief && !oomOnly) {
16415                PrintWriter out = categoryPw != null ? categoryPw : pw;
16416                if (!isCompact) {
16417                    out.println();
16418                    out.println("Total PSS by category:");
16419                }
16420                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16421            }
16422            if (!isCompact) {
16423                pw.println();
16424            }
16425            MemInfoReader memInfo = new MemInfoReader();
16426            memInfo.readMemInfo();
16427            if (nativeProcTotalPss > 0) {
16428                synchronized (this) {
16429                    final long cachedKb = memInfo.getCachedSizeKb();
16430                    final long freeKb = memInfo.getFreeSizeKb();
16431                    final long zramKb = memInfo.getZramTotalSizeKb();
16432                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16433                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16434                            kernelKb*1024, nativeProcTotalPss*1024);
16435                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16436                            nativeProcTotalPss);
16437                }
16438            }
16439            if (!brief) {
16440                if (!isCompact) {
16441                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16442                    pw.print(" (status ");
16443                    switch (mLastMemoryLevel) {
16444                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16445                            pw.println("normal)");
16446                            break;
16447                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16448                            pw.println("moderate)");
16449                            break;
16450                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16451                            pw.println("low)");
16452                            break;
16453                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16454                            pw.println("critical)");
16455                            break;
16456                        default:
16457                            pw.print(mLastMemoryLevel);
16458                            pw.println(")");
16459                            break;
16460                    }
16461                    pw.print(" Free RAM: ");
16462                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16463                            + memInfo.getFreeSizeKb()));
16464                    pw.print(" (");
16465                    pw.print(stringifyKBSize(cachedPss));
16466                    pw.print(" cached pss + ");
16467                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16468                    pw.print(" cached kernel + ");
16469                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16470                    pw.println(" free)");
16471                } else {
16472                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16473                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16474                            + memInfo.getFreeSizeKb()); pw.print(",");
16475                    pw.println(totalPss - cachedPss);
16476                }
16477            }
16478            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16479                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16480                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16481            if (!isCompact) {
16482                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16483                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16484                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16485                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16486                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16487            } else {
16488                pw.print("lostram,"); pw.println(lostRAM);
16489            }
16490            if (!brief) {
16491                if (memInfo.getZramTotalSizeKb() != 0) {
16492                    if (!isCompact) {
16493                        pw.print("     ZRAM: ");
16494                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16495                                pw.print(" physical used for ");
16496                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16497                                        - memInfo.getSwapFreeSizeKb()));
16498                                pw.print(" in swap (");
16499                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16500                                pw.println(" total swap)");
16501                    } else {
16502                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16503                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16504                                pw.println(memInfo.getSwapFreeSizeKb());
16505                    }
16506                }
16507                final long[] ksm = getKsmInfo();
16508                if (!isCompact) {
16509                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16510                            || ksm[KSM_VOLATILE] != 0) {
16511                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16512                                pw.print(" saved from shared ");
16513                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16514                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16515                                pw.print(" unshared; ");
16516                                pw.print(stringifyKBSize(
16517                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16518                    }
16519                    pw.print("   Tuning: ");
16520                    pw.print(ActivityManager.staticGetMemoryClass());
16521                    pw.print(" (large ");
16522                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16523                    pw.print("), oom ");
16524                    pw.print(stringifySize(
16525                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16526                    pw.print(", restore limit ");
16527                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16528                    if (ActivityManager.isLowRamDeviceStatic()) {
16529                        pw.print(" (low-ram)");
16530                    }
16531                    if (ActivityManager.isHighEndGfx()) {
16532                        pw.print(" (high-end-gfx)");
16533                    }
16534                    pw.println();
16535                } else {
16536                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16537                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16538                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16539                    pw.print("tuning,");
16540                    pw.print(ActivityManager.staticGetMemoryClass());
16541                    pw.print(',');
16542                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16543                    pw.print(',');
16544                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16545                    if (ActivityManager.isLowRamDeviceStatic()) {
16546                        pw.print(",low-ram");
16547                    }
16548                    if (ActivityManager.isHighEndGfx()) {
16549                        pw.print(",high-end-gfx");
16550                    }
16551                    pw.println();
16552                }
16553            }
16554        }
16555    }
16556
16557    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16558            long memtrack, String name) {
16559        sb.append("  ");
16560        sb.append(ProcessList.makeOomAdjString(oomAdj));
16561        sb.append(' ');
16562        sb.append(ProcessList.makeProcStateString(procState));
16563        sb.append(' ');
16564        ProcessList.appendRamKb(sb, pss);
16565        sb.append(": ");
16566        sb.append(name);
16567        if (memtrack > 0) {
16568            sb.append(" (");
16569            sb.append(stringifyKBSize(memtrack));
16570            sb.append(" memtrack)");
16571        }
16572    }
16573
16574    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16575        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16576        sb.append(" (pid ");
16577        sb.append(mi.pid);
16578        sb.append(") ");
16579        sb.append(mi.adjType);
16580        sb.append('\n');
16581        if (mi.adjReason != null) {
16582            sb.append("                      ");
16583            sb.append(mi.adjReason);
16584            sb.append('\n');
16585        }
16586    }
16587
16588    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16589        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16590        for (int i=0, N=memInfos.size(); i<N; i++) {
16591            ProcessMemInfo mi = memInfos.get(i);
16592            infoMap.put(mi.pid, mi);
16593        }
16594        updateCpuStatsNow();
16595        long[] memtrackTmp = new long[1];
16596        final List<ProcessCpuTracker.Stats> stats;
16597        // Get a list of Stats that have vsize > 0
16598        synchronized (mProcessCpuTracker) {
16599            stats = mProcessCpuTracker.getStats((st) -> {
16600                return st.vsize > 0;
16601            });
16602        }
16603        final int statsCount = stats.size();
16604        for (int i = 0; i < statsCount; i++) {
16605            ProcessCpuTracker.Stats st = stats.get(i);
16606            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16607            if (pss > 0) {
16608                if (infoMap.indexOfKey(st.pid) < 0) {
16609                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16610                            ProcessList.NATIVE_ADJ, -1, "native", null);
16611                    mi.pss = pss;
16612                    mi.memtrack = memtrackTmp[0];
16613                    memInfos.add(mi);
16614                }
16615            }
16616        }
16617
16618        long totalPss = 0;
16619        long totalMemtrack = 0;
16620        for (int i=0, N=memInfos.size(); i<N; i++) {
16621            ProcessMemInfo mi = memInfos.get(i);
16622            if (mi.pss == 0) {
16623                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16624                mi.memtrack = memtrackTmp[0];
16625            }
16626            totalPss += mi.pss;
16627            totalMemtrack += mi.memtrack;
16628        }
16629        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16630            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16631                if (lhs.oomAdj != rhs.oomAdj) {
16632                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16633                }
16634                if (lhs.pss != rhs.pss) {
16635                    return lhs.pss < rhs.pss ? 1 : -1;
16636                }
16637                return 0;
16638            }
16639        });
16640
16641        StringBuilder tag = new StringBuilder(128);
16642        StringBuilder stack = new StringBuilder(128);
16643        tag.append("Low on memory -- ");
16644        appendMemBucket(tag, totalPss, "total", false);
16645        appendMemBucket(stack, totalPss, "total", true);
16646
16647        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16648        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16649        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16650
16651        boolean firstLine = true;
16652        int lastOomAdj = Integer.MIN_VALUE;
16653        long extraNativeRam = 0;
16654        long extraNativeMemtrack = 0;
16655        long cachedPss = 0;
16656        for (int i=0, N=memInfos.size(); i<N; i++) {
16657            ProcessMemInfo mi = memInfos.get(i);
16658
16659            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16660                cachedPss += mi.pss;
16661            }
16662
16663            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16664                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16665                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16666                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16667                if (lastOomAdj != mi.oomAdj) {
16668                    lastOomAdj = mi.oomAdj;
16669                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16670                        tag.append(" / ");
16671                    }
16672                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16673                        if (firstLine) {
16674                            stack.append(":");
16675                            firstLine = false;
16676                        }
16677                        stack.append("\n\t at ");
16678                    } else {
16679                        stack.append("$");
16680                    }
16681                } else {
16682                    tag.append(" ");
16683                    stack.append("$");
16684                }
16685                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16686                    appendMemBucket(tag, mi.pss, mi.name, false);
16687                }
16688                appendMemBucket(stack, mi.pss, mi.name, true);
16689                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16690                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16691                    stack.append("(");
16692                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16693                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16694                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16695                            stack.append(":");
16696                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16697                        }
16698                    }
16699                    stack.append(")");
16700                }
16701            }
16702
16703            appendMemInfo(fullNativeBuilder, mi);
16704            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16705                // The short form only has native processes that are >= 512K.
16706                if (mi.pss >= 512) {
16707                    appendMemInfo(shortNativeBuilder, mi);
16708                } else {
16709                    extraNativeRam += mi.pss;
16710                    extraNativeMemtrack += mi.memtrack;
16711                }
16712            } else {
16713                // Short form has all other details, but if we have collected RAM
16714                // from smaller native processes let's dump a summary of that.
16715                if (extraNativeRam > 0) {
16716                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16717                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16718                    shortNativeBuilder.append('\n');
16719                    extraNativeRam = 0;
16720                }
16721                appendMemInfo(fullJavaBuilder, mi);
16722            }
16723        }
16724
16725        fullJavaBuilder.append("           ");
16726        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16727        fullJavaBuilder.append(": TOTAL");
16728        if (totalMemtrack > 0) {
16729            fullJavaBuilder.append(" (");
16730            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16731            fullJavaBuilder.append(" memtrack)");
16732        } else {
16733        }
16734        fullJavaBuilder.append("\n");
16735
16736        MemInfoReader memInfo = new MemInfoReader();
16737        memInfo.readMemInfo();
16738        final long[] infos = memInfo.getRawInfo();
16739
16740        StringBuilder memInfoBuilder = new StringBuilder(1024);
16741        Debug.getMemInfo(infos);
16742        memInfoBuilder.append("  MemInfo: ");
16743        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16744        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16745        memInfoBuilder.append(stringifyKBSize(
16746                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16747        memInfoBuilder.append(stringifyKBSize(
16748                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16749        memInfoBuilder.append(stringifyKBSize(
16750                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16751        memInfoBuilder.append("           ");
16752        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16753        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16754        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16755        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16756        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16757            memInfoBuilder.append("  ZRAM: ");
16758            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16759            memInfoBuilder.append(" RAM, ");
16760            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16761            memInfoBuilder.append(" swap total, ");
16762            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16763            memInfoBuilder.append(" swap free\n");
16764        }
16765        final long[] ksm = getKsmInfo();
16766        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16767                || ksm[KSM_VOLATILE] != 0) {
16768            memInfoBuilder.append("  KSM: ");
16769            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16770            memInfoBuilder.append(" saved from shared ");
16771            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16772            memInfoBuilder.append("\n       ");
16773            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16774            memInfoBuilder.append(" unshared; ");
16775            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16776            memInfoBuilder.append(" volatile\n");
16777        }
16778        memInfoBuilder.append("  Free RAM: ");
16779        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16780                + memInfo.getFreeSizeKb()));
16781        memInfoBuilder.append("\n");
16782        memInfoBuilder.append("  Used RAM: ");
16783        memInfoBuilder.append(stringifyKBSize(
16784                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16785        memInfoBuilder.append("\n");
16786        memInfoBuilder.append("  Lost RAM: ");
16787        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16788                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16789                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16790        memInfoBuilder.append("\n");
16791        Slog.i(TAG, "Low on memory:");
16792        Slog.i(TAG, shortNativeBuilder.toString());
16793        Slog.i(TAG, fullJavaBuilder.toString());
16794        Slog.i(TAG, memInfoBuilder.toString());
16795
16796        StringBuilder dropBuilder = new StringBuilder(1024);
16797        /*
16798        StringWriter oomSw = new StringWriter();
16799        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16800        StringWriter catSw = new StringWriter();
16801        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16802        String[] emptyArgs = new String[] { };
16803        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16804        oomPw.flush();
16805        String oomString = oomSw.toString();
16806        */
16807        dropBuilder.append("Low on memory:");
16808        dropBuilder.append(stack);
16809        dropBuilder.append('\n');
16810        dropBuilder.append(fullNativeBuilder);
16811        dropBuilder.append(fullJavaBuilder);
16812        dropBuilder.append('\n');
16813        dropBuilder.append(memInfoBuilder);
16814        dropBuilder.append('\n');
16815        /*
16816        dropBuilder.append(oomString);
16817        dropBuilder.append('\n');
16818        */
16819        StringWriter catSw = new StringWriter();
16820        synchronized (ActivityManagerService.this) {
16821            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16822            String[] emptyArgs = new String[] { };
16823            catPw.println();
16824            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16825            catPw.println();
16826            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16827                    false, null).dumpLocked();
16828            catPw.println();
16829            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16830            catPw.flush();
16831        }
16832        dropBuilder.append(catSw.toString());
16833        addErrorToDropBox("lowmem", null, "system_server", null,
16834                null, tag.toString(), dropBuilder.toString(), null, null);
16835        //Slog.i(TAG, "Sent to dropbox:");
16836        //Slog.i(TAG, dropBuilder.toString());
16837        synchronized (ActivityManagerService.this) {
16838            long now = SystemClock.uptimeMillis();
16839            if (mLastMemUsageReportTime < now) {
16840                mLastMemUsageReportTime = now;
16841            }
16842        }
16843    }
16844
16845    /**
16846     * Searches array of arguments for the specified string
16847     * @param args array of argument strings
16848     * @param value value to search for
16849     * @return true if the value is contained in the array
16850     */
16851    private static boolean scanArgs(String[] args, String value) {
16852        if (args != null) {
16853            for (String arg : args) {
16854                if (value.equals(arg)) {
16855                    return true;
16856                }
16857            }
16858        }
16859        return false;
16860    }
16861
16862    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16863            ContentProviderRecord cpr, boolean always) {
16864        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16865
16866        if (!inLaunching || always) {
16867            synchronized (cpr) {
16868                cpr.launchingApp = null;
16869                cpr.notifyAll();
16870            }
16871            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16872            String names[] = cpr.info.authority.split(";");
16873            for (int j = 0; j < names.length; j++) {
16874                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16875            }
16876        }
16877
16878        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16879            ContentProviderConnection conn = cpr.connections.get(i);
16880            if (conn.waiting) {
16881                // If this connection is waiting for the provider, then we don't
16882                // need to mess with its process unless we are always removing
16883                // or for some reason the provider is not currently launching.
16884                if (inLaunching && !always) {
16885                    continue;
16886                }
16887            }
16888            ProcessRecord capp = conn.client;
16889            conn.dead = true;
16890            if (conn.stableCount > 0) {
16891                if (!capp.persistent && capp.thread != null
16892                        && capp.pid != 0
16893                        && capp.pid != MY_PID) {
16894                    capp.kill("depends on provider "
16895                            + cpr.name.flattenToShortString()
16896                            + " in dying proc " + (proc != null ? proc.processName : "??")
16897                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16898                }
16899            } else if (capp.thread != null && conn.provider.provider != null) {
16900                try {
16901                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16902                } catch (RemoteException e) {
16903                }
16904                // In the protocol here, we don't expect the client to correctly
16905                // clean up this connection, we'll just remove it.
16906                cpr.connections.remove(i);
16907                if (conn.client.conProviders.remove(conn)) {
16908                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16909                }
16910            }
16911        }
16912
16913        if (inLaunching && always) {
16914            mLaunchingProviders.remove(cpr);
16915        }
16916        return inLaunching;
16917    }
16918
16919    /**
16920     * Main code for cleaning up a process when it has gone away.  This is
16921     * called both as a result of the process dying, or directly when stopping
16922     * a process when running in single process mode.
16923     *
16924     * @return Returns true if the given process has been restarted, so the
16925     * app that was passed in must remain on the process lists.
16926     */
16927    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16928            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16929        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16930        if (index >= 0) {
16931            removeLruProcessLocked(app);
16932            ProcessList.remove(app.pid);
16933        }
16934
16935        mProcessesToGc.remove(app);
16936        mPendingPssProcesses.remove(app);
16937
16938        // Dismiss any open dialogs.
16939        if (app.crashDialog != null && !app.forceCrashReport) {
16940            app.crashDialog.dismiss();
16941            app.crashDialog = null;
16942        }
16943        if (app.anrDialog != null) {
16944            app.anrDialog.dismiss();
16945            app.anrDialog = null;
16946        }
16947        if (app.waitDialog != null) {
16948            app.waitDialog.dismiss();
16949            app.waitDialog = null;
16950        }
16951
16952        app.crashing = false;
16953        app.notResponding = false;
16954
16955        app.resetPackageList(mProcessStats);
16956        app.unlinkDeathRecipient();
16957        app.makeInactive(mProcessStats);
16958        app.waitingToKill = null;
16959        app.forcingToForeground = null;
16960        updateProcessForegroundLocked(app, false, false);
16961        app.foregroundActivities = false;
16962        app.hasShownUi = false;
16963        app.treatLikeActivity = false;
16964        app.hasAboveClient = false;
16965        app.hasClientActivities = false;
16966
16967        mServices.killServicesLocked(app, allowRestart);
16968
16969        boolean restart = false;
16970
16971        // Remove published content providers.
16972        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16973            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16974            final boolean always = app.bad || !allowRestart;
16975            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16976            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16977                // We left the provider in the launching list, need to
16978                // restart it.
16979                restart = true;
16980            }
16981
16982            cpr.provider = null;
16983            cpr.proc = null;
16984        }
16985        app.pubProviders.clear();
16986
16987        // Take care of any launching providers waiting for this process.
16988        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16989            restart = true;
16990        }
16991
16992        // Unregister from connected content providers.
16993        if (!app.conProviders.isEmpty()) {
16994            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16995                ContentProviderConnection conn = app.conProviders.get(i);
16996                conn.provider.connections.remove(conn);
16997                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16998                        conn.provider.name);
16999            }
17000            app.conProviders.clear();
17001        }
17002
17003        // At this point there may be remaining entries in mLaunchingProviders
17004        // where we were the only one waiting, so they are no longer of use.
17005        // Look for these and clean up if found.
17006        // XXX Commented out for now.  Trying to figure out a way to reproduce
17007        // the actual situation to identify what is actually going on.
17008        if (false) {
17009            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17010                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17011                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17012                    synchronized (cpr) {
17013                        cpr.launchingApp = null;
17014                        cpr.notifyAll();
17015                    }
17016                }
17017            }
17018        }
17019
17020        skipCurrentReceiverLocked(app);
17021
17022        // Unregister any receivers.
17023        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17024            removeReceiverLocked(app.receivers.valueAt(i));
17025        }
17026        app.receivers.clear();
17027
17028        // If the app is undergoing backup, tell the backup manager about it
17029        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17030            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17031                    + mBackupTarget.appInfo + " died during backup");
17032            mHandler.post(new Runnable() {
17033                @Override
17034                public void run(){
17035                    try {
17036                        IBackupManager bm = IBackupManager.Stub.asInterface(
17037                                ServiceManager.getService(Context.BACKUP_SERVICE));
17038                        bm.agentDisconnected(app.info.packageName);
17039                    } catch (RemoteException e) {
17040                        // can't happen; backup manager is local
17041                    }
17042                }
17043            });
17044        }
17045
17046        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17047            ProcessChangeItem item = mPendingProcessChanges.get(i);
17048            if (item.pid == app.pid) {
17049                mPendingProcessChanges.remove(i);
17050                mAvailProcessChanges.add(item);
17051            }
17052        }
17053        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17054                null).sendToTarget();
17055
17056        // If the caller is restarting this app, then leave it in its
17057        // current lists and let the caller take care of it.
17058        if (restarting) {
17059            return false;
17060        }
17061
17062        if (!app.persistent || app.isolated) {
17063            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17064                    "Removing non-persistent process during cleanup: " + app);
17065            if (!replacingPid) {
17066                removeProcessNameLocked(app.processName, app.uid, app);
17067            }
17068            if (mHeavyWeightProcess == app) {
17069                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17070                        mHeavyWeightProcess.userId, 0));
17071                mHeavyWeightProcess = null;
17072            }
17073        } else if (!app.removed) {
17074            // This app is persistent, so we need to keep its record around.
17075            // If it is not already on the pending app list, add it there
17076            // and start a new process for it.
17077            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17078                mPersistentStartingProcesses.add(app);
17079                restart = true;
17080            }
17081        }
17082        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17083                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17084        mProcessesOnHold.remove(app);
17085
17086        if (app == mHomeProcess) {
17087            mHomeProcess = null;
17088        }
17089        if (app == mPreviousProcess) {
17090            mPreviousProcess = null;
17091        }
17092
17093        if (restart && !app.isolated) {
17094            // We have components that still need to be running in the
17095            // process, so re-launch it.
17096            if (index < 0) {
17097                ProcessList.remove(app.pid);
17098            }
17099            addProcessNameLocked(app);
17100            startProcessLocked(app, "restart", app.processName);
17101            return true;
17102        } else if (app.pid > 0 && app.pid != MY_PID) {
17103            // Goodbye!
17104            boolean removed;
17105            synchronized (mPidsSelfLocked) {
17106                mPidsSelfLocked.remove(app.pid);
17107                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17108            }
17109            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17110            if (app.isolated) {
17111                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17112            }
17113            app.setPid(0);
17114        }
17115        return false;
17116    }
17117
17118    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17119        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17120            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17121            if (cpr.launchingApp == app) {
17122                return true;
17123            }
17124        }
17125        return false;
17126    }
17127
17128    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17129        // Look through the content providers we are waiting to have launched,
17130        // and if any run in this process then either schedule a restart of
17131        // the process or kill the client waiting for it if this process has
17132        // gone bad.
17133        boolean restart = false;
17134        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17135            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17136            if (cpr.launchingApp == app) {
17137                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17138                    restart = true;
17139                } else {
17140                    removeDyingProviderLocked(app, cpr, true);
17141                }
17142            }
17143        }
17144        return restart;
17145    }
17146
17147    // =========================================================
17148    // SERVICES
17149    // =========================================================
17150
17151    @Override
17152    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17153            int flags) {
17154        enforceNotIsolatedCaller("getServices");
17155        synchronized (this) {
17156            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17157        }
17158    }
17159
17160    @Override
17161    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17162        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17163        synchronized (this) {
17164            return mServices.getRunningServiceControlPanelLocked(name);
17165        }
17166    }
17167
17168    @Override
17169    public ComponentName startService(IApplicationThread caller, Intent service,
17170            String resolvedType, String callingPackage, int userId)
17171            throws TransactionTooLargeException {
17172        enforceNotIsolatedCaller("startService");
17173        // Refuse possible leaked file descriptors
17174        if (service != null && service.hasFileDescriptors() == true) {
17175            throw new IllegalArgumentException("File descriptors passed in Intent");
17176        }
17177
17178        if (callingPackage == null) {
17179            throw new IllegalArgumentException("callingPackage cannot be null");
17180        }
17181
17182        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17183                "startService: " + service + " type=" + resolvedType);
17184        synchronized(this) {
17185            final int callingPid = Binder.getCallingPid();
17186            final int callingUid = Binder.getCallingUid();
17187            final long origId = Binder.clearCallingIdentity();
17188            ComponentName res = mServices.startServiceLocked(caller, service,
17189                    resolvedType, callingPid, callingUid, callingPackage, userId);
17190            Binder.restoreCallingIdentity(origId);
17191            return res;
17192        }
17193    }
17194
17195    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17196            String callingPackage, int userId)
17197            throws TransactionTooLargeException {
17198        synchronized(this) {
17199            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17200                    "startServiceInPackage: " + service + " type=" + resolvedType);
17201            final long origId = Binder.clearCallingIdentity();
17202            ComponentName res = mServices.startServiceLocked(null, service,
17203                    resolvedType, -1, uid, callingPackage, userId);
17204            Binder.restoreCallingIdentity(origId);
17205            return res;
17206        }
17207    }
17208
17209    @Override
17210    public int stopService(IApplicationThread caller, Intent service,
17211            String resolvedType, int userId) {
17212        enforceNotIsolatedCaller("stopService");
17213        // Refuse possible leaked file descriptors
17214        if (service != null && service.hasFileDescriptors() == true) {
17215            throw new IllegalArgumentException("File descriptors passed in Intent");
17216        }
17217
17218        synchronized(this) {
17219            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17220        }
17221    }
17222
17223    @Override
17224    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17225        enforceNotIsolatedCaller("peekService");
17226        // Refuse possible leaked file descriptors
17227        if (service != null && service.hasFileDescriptors() == true) {
17228            throw new IllegalArgumentException("File descriptors passed in Intent");
17229        }
17230
17231        if (callingPackage == null) {
17232            throw new IllegalArgumentException("callingPackage cannot be null");
17233        }
17234
17235        synchronized(this) {
17236            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17237        }
17238    }
17239
17240    @Override
17241    public boolean stopServiceToken(ComponentName className, IBinder token,
17242            int startId) {
17243        synchronized(this) {
17244            return mServices.stopServiceTokenLocked(className, token, startId);
17245        }
17246    }
17247
17248    @Override
17249    public void setServiceForeground(ComponentName className, IBinder token,
17250            int id, Notification notification, int flags) {
17251        synchronized(this) {
17252            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17253        }
17254    }
17255
17256    @Override
17257    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17258            boolean requireFull, String name, String callerPackage) {
17259        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17260                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17261    }
17262
17263    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17264            String className, int flags) {
17265        boolean result = false;
17266        // For apps that don't have pre-defined UIDs, check for permission
17267        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17268            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17269                if (ActivityManager.checkUidPermission(
17270                        INTERACT_ACROSS_USERS,
17271                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17272                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17273                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17274                            + " requests FLAG_SINGLE_USER, but app does not hold "
17275                            + INTERACT_ACROSS_USERS;
17276                    Slog.w(TAG, msg);
17277                    throw new SecurityException(msg);
17278                }
17279                // Permission passed
17280                result = true;
17281            }
17282        } else if ("system".equals(componentProcessName)) {
17283            result = true;
17284        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17285            // Phone app and persistent apps are allowed to export singleuser providers.
17286            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17287                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17288        }
17289        if (DEBUG_MU) Slog.v(TAG_MU,
17290                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17291                + Integer.toHexString(flags) + ") = " + result);
17292        return result;
17293    }
17294
17295    /**
17296     * Checks to see if the caller is in the same app as the singleton
17297     * component, or the component is in a special app. It allows special apps
17298     * to export singleton components but prevents exporting singleton
17299     * components for regular apps.
17300     */
17301    boolean isValidSingletonCall(int callingUid, int componentUid) {
17302        int componentAppId = UserHandle.getAppId(componentUid);
17303        return UserHandle.isSameApp(callingUid, componentUid)
17304                || componentAppId == Process.SYSTEM_UID
17305                || componentAppId == Process.PHONE_UID
17306                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17307                        == PackageManager.PERMISSION_GRANTED;
17308    }
17309
17310    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17311            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17312            int userId) throws TransactionTooLargeException {
17313        enforceNotIsolatedCaller("bindService");
17314
17315        // Refuse possible leaked file descriptors
17316        if (service != null && service.hasFileDescriptors() == true) {
17317            throw new IllegalArgumentException("File descriptors passed in Intent");
17318        }
17319
17320        if (callingPackage == null) {
17321            throw new IllegalArgumentException("callingPackage cannot be null");
17322        }
17323
17324        synchronized(this) {
17325            return mServices.bindServiceLocked(caller, token, service,
17326                    resolvedType, connection, flags, callingPackage, userId);
17327        }
17328    }
17329
17330    public boolean unbindService(IServiceConnection connection) {
17331        synchronized (this) {
17332            return mServices.unbindServiceLocked(connection);
17333        }
17334    }
17335
17336    public void publishService(IBinder token, Intent intent, IBinder service) {
17337        // Refuse possible leaked file descriptors
17338        if (intent != null && intent.hasFileDescriptors() == true) {
17339            throw new IllegalArgumentException("File descriptors passed in Intent");
17340        }
17341
17342        synchronized(this) {
17343            if (!(token instanceof ServiceRecord)) {
17344                throw new IllegalArgumentException("Invalid service token");
17345            }
17346            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17347        }
17348    }
17349
17350    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17351        // Refuse possible leaked file descriptors
17352        if (intent != null && intent.hasFileDescriptors() == true) {
17353            throw new IllegalArgumentException("File descriptors passed in Intent");
17354        }
17355
17356        synchronized(this) {
17357            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17358        }
17359    }
17360
17361    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17362        synchronized(this) {
17363            if (!(token instanceof ServiceRecord)) {
17364                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17365                throw new IllegalArgumentException("Invalid service token");
17366            }
17367            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17368        }
17369    }
17370
17371    // =========================================================
17372    // BACKUP AND RESTORE
17373    // =========================================================
17374
17375    // Cause the target app to be launched if necessary and its backup agent
17376    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17377    // activity manager to announce its creation.
17378    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17379        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17380        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17381
17382        IPackageManager pm = AppGlobals.getPackageManager();
17383        ApplicationInfo app = null;
17384        try {
17385            app = pm.getApplicationInfo(packageName, 0, userId);
17386        } catch (RemoteException e) {
17387            // can't happen; package manager is process-local
17388        }
17389        if (app == null) {
17390            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17391            return false;
17392        }
17393
17394        synchronized(this) {
17395            // !!! TODO: currently no check here that we're already bound
17396            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17397            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17398            synchronized (stats) {
17399                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17400            }
17401
17402            // Backup agent is now in use, its package can't be stopped.
17403            try {
17404                AppGlobals.getPackageManager().setPackageStoppedState(
17405                        app.packageName, false, UserHandle.getUserId(app.uid));
17406            } catch (RemoteException e) {
17407            } catch (IllegalArgumentException e) {
17408                Slog.w(TAG, "Failed trying to unstop package "
17409                        + app.packageName + ": " + e);
17410            }
17411
17412            BackupRecord r = new BackupRecord(ss, app, backupMode);
17413            ComponentName hostingName =
17414                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17415                            ? new ComponentName(app.packageName, app.backupAgentName)
17416                            : new ComponentName("android", "FullBackupAgent");
17417            // startProcessLocked() returns existing proc's record if it's already running
17418            ProcessRecord proc = startProcessLocked(app.processName, app,
17419                    false, 0, "backup", hostingName, false, false, false);
17420            if (proc == null) {
17421                Slog.e(TAG, "Unable to start backup agent process " + r);
17422                return false;
17423            }
17424
17425            // If the app is a regular app (uid >= 10000) and not the system server or phone
17426            // process, etc, then mark it as being in full backup so that certain calls to the
17427            // process can be blocked. This is not reset to false anywhere because we kill the
17428            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17429            if (UserHandle.isApp(app.uid) &&
17430                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17431                proc.inFullBackup = true;
17432            }
17433            r.app = proc;
17434            mBackupTarget = r;
17435            mBackupAppName = app.packageName;
17436
17437            // Try not to kill the process during backup
17438            updateOomAdjLocked(proc);
17439
17440            // If the process is already attached, schedule the creation of the backup agent now.
17441            // If it is not yet live, this will be done when it attaches to the framework.
17442            if (proc.thread != null) {
17443                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17444                try {
17445                    proc.thread.scheduleCreateBackupAgent(app,
17446                            compatibilityInfoForPackageLocked(app), backupMode);
17447                } catch (RemoteException e) {
17448                    // Will time out on the backup manager side
17449                }
17450            } else {
17451                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17452            }
17453            // Invariants: at this point, the target app process exists and the application
17454            // is either already running or in the process of coming up.  mBackupTarget and
17455            // mBackupAppName describe the app, so that when it binds back to the AM we
17456            // know that it's scheduled for a backup-agent operation.
17457        }
17458
17459        return true;
17460    }
17461
17462    @Override
17463    public void clearPendingBackup() {
17464        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17465        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17466
17467        synchronized (this) {
17468            mBackupTarget = null;
17469            mBackupAppName = null;
17470        }
17471    }
17472
17473    // A backup agent has just come up
17474    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17475        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17476                + " = " + agent);
17477
17478        synchronized(this) {
17479            if (!agentPackageName.equals(mBackupAppName)) {
17480                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17481                return;
17482            }
17483        }
17484
17485        long oldIdent = Binder.clearCallingIdentity();
17486        try {
17487            IBackupManager bm = IBackupManager.Stub.asInterface(
17488                    ServiceManager.getService(Context.BACKUP_SERVICE));
17489            bm.agentConnected(agentPackageName, agent);
17490        } catch (RemoteException e) {
17491            // can't happen; the backup manager service is local
17492        } catch (Exception e) {
17493            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17494            e.printStackTrace();
17495        } finally {
17496            Binder.restoreCallingIdentity(oldIdent);
17497        }
17498    }
17499
17500    // done with this agent
17501    public void unbindBackupAgent(ApplicationInfo appInfo) {
17502        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17503        if (appInfo == null) {
17504            Slog.w(TAG, "unbind backup agent for null app");
17505            return;
17506        }
17507
17508        synchronized(this) {
17509            try {
17510                if (mBackupAppName == null) {
17511                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17512                    return;
17513                }
17514
17515                if (!mBackupAppName.equals(appInfo.packageName)) {
17516                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17517                    return;
17518                }
17519
17520                // Not backing this app up any more; reset its OOM adjustment
17521                final ProcessRecord proc = mBackupTarget.app;
17522                updateOomAdjLocked(proc);
17523
17524                // If the app crashed during backup, 'thread' will be null here
17525                if (proc.thread != null) {
17526                    try {
17527                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17528                                compatibilityInfoForPackageLocked(appInfo));
17529                    } catch (Exception e) {
17530                        Slog.e(TAG, "Exception when unbinding backup agent:");
17531                        e.printStackTrace();
17532                    }
17533                }
17534            } finally {
17535                mBackupTarget = null;
17536                mBackupAppName = null;
17537            }
17538        }
17539    }
17540    // =========================================================
17541    // BROADCASTS
17542    // =========================================================
17543
17544    boolean isPendingBroadcastProcessLocked(int pid) {
17545        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17546                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17547    }
17548
17549    void skipPendingBroadcastLocked(int pid) {
17550            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17551            for (BroadcastQueue queue : mBroadcastQueues) {
17552                queue.skipPendingBroadcastLocked(pid);
17553            }
17554    }
17555
17556    // The app just attached; send any pending broadcasts that it should receive
17557    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17558        boolean didSomething = false;
17559        for (BroadcastQueue queue : mBroadcastQueues) {
17560            didSomething |= queue.sendPendingBroadcastsLocked(app);
17561        }
17562        return didSomething;
17563    }
17564
17565    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17566            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17567        enforceNotIsolatedCaller("registerReceiver");
17568        ArrayList<Intent> stickyIntents = null;
17569        ProcessRecord callerApp = null;
17570        int callingUid;
17571        int callingPid;
17572        synchronized(this) {
17573            if (caller != null) {
17574                callerApp = getRecordForAppLocked(caller);
17575                if (callerApp == null) {
17576                    throw new SecurityException(
17577                            "Unable to find app for caller " + caller
17578                            + " (pid=" + Binder.getCallingPid()
17579                            + ") when registering receiver " + receiver);
17580                }
17581                if (callerApp.info.uid != Process.SYSTEM_UID &&
17582                        !callerApp.pkgList.containsKey(callerPackage) &&
17583                        !"android".equals(callerPackage)) {
17584                    throw new SecurityException("Given caller package " + callerPackage
17585                            + " is not running in process " + callerApp);
17586                }
17587                callingUid = callerApp.info.uid;
17588                callingPid = callerApp.pid;
17589            } else {
17590                callerPackage = null;
17591                callingUid = Binder.getCallingUid();
17592                callingPid = Binder.getCallingPid();
17593            }
17594
17595            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17596                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17597
17598            Iterator<String> actions = filter.actionsIterator();
17599            if (actions == null) {
17600                ArrayList<String> noAction = new ArrayList<String>(1);
17601                noAction.add(null);
17602                actions = noAction.iterator();
17603            }
17604
17605            // Collect stickies of users
17606            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17607            while (actions.hasNext()) {
17608                String action = actions.next();
17609                for (int id : userIds) {
17610                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17611                    if (stickies != null) {
17612                        ArrayList<Intent> intents = stickies.get(action);
17613                        if (intents != null) {
17614                            if (stickyIntents == null) {
17615                                stickyIntents = new ArrayList<Intent>();
17616                            }
17617                            stickyIntents.addAll(intents);
17618                        }
17619                    }
17620                }
17621            }
17622        }
17623
17624        ArrayList<Intent> allSticky = null;
17625        if (stickyIntents != null) {
17626            final ContentResolver resolver = mContext.getContentResolver();
17627            // Look for any matching sticky broadcasts...
17628            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17629                Intent intent = stickyIntents.get(i);
17630                // If intent has scheme "content", it will need to acccess
17631                // provider that needs to lock mProviderMap in ActivityThread
17632                // and also it may need to wait application response, so we
17633                // cannot lock ActivityManagerService here.
17634                if (filter.match(resolver, intent, true, TAG) >= 0) {
17635                    if (allSticky == null) {
17636                        allSticky = new ArrayList<Intent>();
17637                    }
17638                    allSticky.add(intent);
17639                }
17640            }
17641        }
17642
17643        // The first sticky in the list is returned directly back to the client.
17644        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17645        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17646        if (receiver == null) {
17647            return sticky;
17648        }
17649
17650        synchronized (this) {
17651            if (callerApp != null && (callerApp.thread == null
17652                    || callerApp.thread.asBinder() != caller.asBinder())) {
17653                // Original caller already died
17654                return null;
17655            }
17656            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17657            if (rl == null) {
17658                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17659                        userId, receiver);
17660                if (rl.app != null) {
17661                    rl.app.receivers.add(rl);
17662                } else {
17663                    try {
17664                        receiver.asBinder().linkToDeath(rl, 0);
17665                    } catch (RemoteException e) {
17666                        return sticky;
17667                    }
17668                    rl.linkedToDeath = true;
17669                }
17670                mRegisteredReceivers.put(receiver.asBinder(), rl);
17671            } else if (rl.uid != callingUid) {
17672                throw new IllegalArgumentException(
17673                        "Receiver requested to register for uid " + callingUid
17674                        + " was previously registered for uid " + rl.uid);
17675            } else if (rl.pid != callingPid) {
17676                throw new IllegalArgumentException(
17677                        "Receiver requested to register for pid " + callingPid
17678                        + " was previously registered for pid " + rl.pid);
17679            } else if (rl.userId != userId) {
17680                throw new IllegalArgumentException(
17681                        "Receiver requested to register for user " + userId
17682                        + " was previously registered for user " + rl.userId);
17683            }
17684            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17685                    permission, callingUid, userId);
17686            rl.add(bf);
17687            if (!bf.debugCheck()) {
17688                Slog.w(TAG, "==> For Dynamic broadcast");
17689            }
17690            mReceiverResolver.addFilter(bf);
17691
17692            // Enqueue broadcasts for all existing stickies that match
17693            // this filter.
17694            if (allSticky != null) {
17695                ArrayList receivers = new ArrayList();
17696                receivers.add(bf);
17697
17698                final int stickyCount = allSticky.size();
17699                for (int i = 0; i < stickyCount; i++) {
17700                    Intent intent = allSticky.get(i);
17701                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17702                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17703                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17704                            null, 0, null, null, false, true, true, -1);
17705                    queue.enqueueParallelBroadcastLocked(r);
17706                    queue.scheduleBroadcastsLocked();
17707                }
17708            }
17709
17710            return sticky;
17711        }
17712    }
17713
17714    public void unregisterReceiver(IIntentReceiver receiver) {
17715        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17716
17717        final long origId = Binder.clearCallingIdentity();
17718        try {
17719            boolean doTrim = false;
17720
17721            synchronized(this) {
17722                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17723                if (rl != null) {
17724                    final BroadcastRecord r = rl.curBroadcast;
17725                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17726                        final boolean doNext = r.queue.finishReceiverLocked(
17727                                r, r.resultCode, r.resultData, r.resultExtras,
17728                                r.resultAbort, false);
17729                        if (doNext) {
17730                            doTrim = true;
17731                            r.queue.processNextBroadcast(false);
17732                        }
17733                    }
17734
17735                    if (rl.app != null) {
17736                        rl.app.receivers.remove(rl);
17737                    }
17738                    removeReceiverLocked(rl);
17739                    if (rl.linkedToDeath) {
17740                        rl.linkedToDeath = false;
17741                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17742                    }
17743                }
17744            }
17745
17746            // If we actually concluded any broadcasts, we might now be able
17747            // to trim the recipients' apps from our working set
17748            if (doTrim) {
17749                trimApplications();
17750                return;
17751            }
17752
17753        } finally {
17754            Binder.restoreCallingIdentity(origId);
17755        }
17756    }
17757
17758    void removeReceiverLocked(ReceiverList rl) {
17759        mRegisteredReceivers.remove(rl.receiver.asBinder());
17760        for (int i = rl.size() - 1; i >= 0; i--) {
17761            mReceiverResolver.removeFilter(rl.get(i));
17762        }
17763    }
17764
17765    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17766        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17767            ProcessRecord r = mLruProcesses.get(i);
17768            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17769                try {
17770                    r.thread.dispatchPackageBroadcast(cmd, packages);
17771                } catch (RemoteException ex) {
17772                }
17773            }
17774        }
17775    }
17776
17777    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17778            int callingUid, int[] users) {
17779        // TODO: come back and remove this assumption to triage all broadcasts
17780        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17781
17782        List<ResolveInfo> receivers = null;
17783        try {
17784            HashSet<ComponentName> singleUserReceivers = null;
17785            boolean scannedFirstReceivers = false;
17786            for (int user : users) {
17787                // Skip users that have Shell restrictions, with exception of always permitted
17788                // Shell broadcasts
17789                if (callingUid == Process.SHELL_UID
17790                        && mUserController.hasUserRestriction(
17791                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17792                        && !isPermittedShellBroadcast(intent)) {
17793                    continue;
17794                }
17795                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17796                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17797                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17798                    // If this is not the system user, we need to check for
17799                    // any receivers that should be filtered out.
17800                    for (int i=0; i<newReceivers.size(); i++) {
17801                        ResolveInfo ri = newReceivers.get(i);
17802                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17803                            newReceivers.remove(i);
17804                            i--;
17805                        }
17806                    }
17807                }
17808                if (newReceivers != null && newReceivers.size() == 0) {
17809                    newReceivers = null;
17810                }
17811                if (receivers == null) {
17812                    receivers = newReceivers;
17813                } else if (newReceivers != null) {
17814                    // We need to concatenate the additional receivers
17815                    // found with what we have do far.  This would be easy,
17816                    // but we also need to de-dup any receivers that are
17817                    // singleUser.
17818                    if (!scannedFirstReceivers) {
17819                        // Collect any single user receivers we had already retrieved.
17820                        scannedFirstReceivers = true;
17821                        for (int i=0; i<receivers.size(); i++) {
17822                            ResolveInfo ri = receivers.get(i);
17823                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17824                                ComponentName cn = new ComponentName(
17825                                        ri.activityInfo.packageName, ri.activityInfo.name);
17826                                if (singleUserReceivers == null) {
17827                                    singleUserReceivers = new HashSet<ComponentName>();
17828                                }
17829                                singleUserReceivers.add(cn);
17830                            }
17831                        }
17832                    }
17833                    // Add the new results to the existing results, tracking
17834                    // and de-dupping single user receivers.
17835                    for (int i=0; i<newReceivers.size(); i++) {
17836                        ResolveInfo ri = newReceivers.get(i);
17837                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17838                            ComponentName cn = new ComponentName(
17839                                    ri.activityInfo.packageName, ri.activityInfo.name);
17840                            if (singleUserReceivers == null) {
17841                                singleUserReceivers = new HashSet<ComponentName>();
17842                            }
17843                            if (!singleUserReceivers.contains(cn)) {
17844                                singleUserReceivers.add(cn);
17845                                receivers.add(ri);
17846                            }
17847                        } else {
17848                            receivers.add(ri);
17849                        }
17850                    }
17851                }
17852            }
17853        } catch (RemoteException ex) {
17854            // pm is in same process, this will never happen.
17855        }
17856        return receivers;
17857    }
17858
17859    private boolean isPermittedShellBroadcast(Intent intent) {
17860        // remote bugreport should always be allowed to be taken
17861        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17862    }
17863
17864    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17865            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17866        final String action = intent.getAction();
17867        if (isProtectedBroadcast
17868                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17869                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17870                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17871                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17872                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17873                || Intent.ACTION_MASTER_CLEAR.equals(action)
17874                || Intent.ACTION_FACTORY_RESET.equals(action)
17875                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17876                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17877                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17878                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17879                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17880            // Broadcast is either protected, or it's a public action that
17881            // we've relaxed, so it's fine for system internals to send.
17882            return;
17883        }
17884
17885        // This broadcast may be a problem...  but there are often system components that
17886        // want to send an internal broadcast to themselves, which is annoying to have to
17887        // explicitly list each action as a protected broadcast, so we will check for that
17888        // one safe case and allow it: an explicit broadcast, only being received by something
17889        // that has protected itself.
17890        if (receivers != null && receivers.size() > 0
17891                && (intent.getPackage() != null || intent.getComponent() != null)) {
17892            boolean allProtected = true;
17893            for (int i = receivers.size()-1; i >= 0; i--) {
17894                Object target = receivers.get(i);
17895                if (target instanceof ResolveInfo) {
17896                    ResolveInfo ri = (ResolveInfo)target;
17897                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17898                        allProtected = false;
17899                        break;
17900                    }
17901                } else {
17902                    BroadcastFilter bf = (BroadcastFilter)target;
17903                    if (bf.requiredPermission == null) {
17904                        allProtected = false;
17905                        break;
17906                    }
17907                }
17908            }
17909            if (allProtected) {
17910                // All safe!
17911                return;
17912            }
17913        }
17914
17915        // The vast majority of broadcasts sent from system internals
17916        // should be protected to avoid security holes, so yell loudly
17917        // to ensure we examine these cases.
17918        if (callerApp != null) {
17919            Log.wtf(TAG, "Sending non-protected broadcast " + action
17920                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17921                    new Throwable());
17922        } else {
17923            Log.wtf(TAG, "Sending non-protected broadcast " + action
17924                            + " from system uid " + UserHandle.formatUid(callingUid)
17925                            + " pkg " + callerPackage,
17926                    new Throwable());
17927        }
17928    }
17929
17930    final int broadcastIntentLocked(ProcessRecord callerApp,
17931            String callerPackage, Intent intent, String resolvedType,
17932            IIntentReceiver resultTo, int resultCode, String resultData,
17933            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17934            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17935        intent = new Intent(intent);
17936
17937        // By default broadcasts do not go to stopped apps.
17938        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17939
17940        // If we have not finished booting, don't allow this to launch new processes.
17941        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17942            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17943        }
17944
17945        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17946                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17947                + " ordered=" + ordered + " userid=" + userId);
17948        if ((resultTo != null) && !ordered) {
17949            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17950        }
17951
17952        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17953                ALLOW_NON_FULL, "broadcast", callerPackage);
17954
17955        // Make sure that the user who is receiving this broadcast is running.
17956        // If not, we will just skip it. Make an exception for shutdown broadcasts
17957        // and upgrade steps.
17958
17959        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17960            if ((callingUid != Process.SYSTEM_UID
17961                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17962                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17963                Slog.w(TAG, "Skipping broadcast of " + intent
17964                        + ": user " + userId + " is stopped");
17965                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17966            }
17967        }
17968
17969        BroadcastOptions brOptions = null;
17970        if (bOptions != null) {
17971            brOptions = new BroadcastOptions(bOptions);
17972            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17973                // See if the caller is allowed to do this.  Note we are checking against
17974                // the actual real caller (not whoever provided the operation as say a
17975                // PendingIntent), because that who is actually supplied the arguments.
17976                if (checkComponentPermission(
17977                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17978                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17979                        != PackageManager.PERMISSION_GRANTED) {
17980                    String msg = "Permission Denial: " + intent.getAction()
17981                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17982                            + ", uid=" + callingUid + ")"
17983                            + " requires "
17984                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17985                    Slog.w(TAG, msg);
17986                    throw new SecurityException(msg);
17987                }
17988            }
17989        }
17990
17991        // Verify that protected broadcasts are only being sent by system code,
17992        // and that system code is only sending protected broadcasts.
17993        final String action = intent.getAction();
17994        final boolean isProtectedBroadcast;
17995        try {
17996            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17997        } catch (RemoteException e) {
17998            Slog.w(TAG, "Remote exception", e);
17999            return ActivityManager.BROADCAST_SUCCESS;
18000        }
18001
18002        final boolean isCallerSystem;
18003        switch (UserHandle.getAppId(callingUid)) {
18004            case Process.ROOT_UID:
18005            case Process.SYSTEM_UID:
18006            case Process.PHONE_UID:
18007            case Process.BLUETOOTH_UID:
18008            case Process.NFC_UID:
18009                if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18010                    isCallerSystem = false;
18011                } else {
18012                    isCallerSystem = true;
18013                }
18014                break;
18015            default:
18016                isCallerSystem = (callerApp != null) && callerApp.persistent;
18017                break;
18018        }
18019
18020        // First line security check before anything else: stop non-system apps from
18021        // sending protected broadcasts.
18022        if (!isCallerSystem) {
18023            if (isProtectedBroadcast) {
18024                String msg = "Permission Denial: not allowed to send broadcast "
18025                        + action + " from pid="
18026                        + callingPid + ", uid=" + callingUid;
18027                Slog.w(TAG, msg);
18028                throw new SecurityException(msg);
18029
18030            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18031                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18032                // Special case for compatibility: we don't want apps to send this,
18033                // but historically it has not been protected and apps may be using it
18034                // to poke their own app widget.  So, instead of making it protected,
18035                // just limit it to the caller.
18036                if (callerPackage == null) {
18037                    String msg = "Permission Denial: not allowed to send broadcast "
18038                            + action + " from unknown caller.";
18039                    Slog.w(TAG, msg);
18040                    throw new SecurityException(msg);
18041                } else if (intent.getComponent() != null) {
18042                    // They are good enough to send to an explicit component...  verify
18043                    // it is being sent to the calling app.
18044                    if (!intent.getComponent().getPackageName().equals(
18045                            callerPackage)) {
18046                        String msg = "Permission Denial: not allowed to send broadcast "
18047                                + action + " to "
18048                                + intent.getComponent().getPackageName() + " from "
18049                                + callerPackage;
18050                        Slog.w(TAG, msg);
18051                        throw new SecurityException(msg);
18052                    }
18053                } else {
18054                    // Limit broadcast to their own package.
18055                    intent.setPackage(callerPackage);
18056                }
18057            }
18058        }
18059
18060        if (action != null) {
18061            switch (action) {
18062                case Intent.ACTION_UID_REMOVED:
18063                case Intent.ACTION_PACKAGE_REMOVED:
18064                case Intent.ACTION_PACKAGE_CHANGED:
18065                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18066                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18067                case Intent.ACTION_PACKAGES_SUSPENDED:
18068                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18069                    // Handle special intents: if this broadcast is from the package
18070                    // manager about a package being removed, we need to remove all of
18071                    // its activities from the history stack.
18072                    if (checkComponentPermission(
18073                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18074                            callingPid, callingUid, -1, true)
18075                            != PackageManager.PERMISSION_GRANTED) {
18076                        String msg = "Permission Denial: " + intent.getAction()
18077                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18078                                + ", uid=" + callingUid + ")"
18079                                + " requires "
18080                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18081                        Slog.w(TAG, msg);
18082                        throw new SecurityException(msg);
18083                    }
18084                    switch (action) {
18085                        case Intent.ACTION_UID_REMOVED:
18086                            final Bundle intentExtras = intent.getExtras();
18087                            final int uid = intentExtras != null
18088                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18089                            if (uid >= 0) {
18090                                mBatteryStatsService.removeUid(uid);
18091                                mAppOpsService.uidRemoved(uid);
18092                            }
18093                            break;
18094                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18095                            // If resources are unavailable just force stop all those packages
18096                            // and flush the attribute cache as well.
18097                            String list[] =
18098                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18099                            if (list != null && list.length > 0) {
18100                                for (int i = 0; i < list.length; i++) {
18101                                    forceStopPackageLocked(list[i], -1, false, true, true,
18102                                            false, false, userId, "storage unmount");
18103                                }
18104                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18105                                sendPackageBroadcastLocked(
18106                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18107                                        list, userId);
18108                            }
18109                            break;
18110                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18111                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18112                            break;
18113                        case Intent.ACTION_PACKAGE_REMOVED:
18114                        case Intent.ACTION_PACKAGE_CHANGED:
18115                            Uri data = intent.getData();
18116                            String ssp;
18117                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18118                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18119                                final boolean replacing =
18120                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18121                                final boolean killProcess =
18122                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18123                                final boolean fullUninstall = removed && !replacing;
18124                                if (removed) {
18125                                    if (killProcess) {
18126                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18127                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18128                                                false, true, true, false, fullUninstall, userId,
18129                                                removed ? "pkg removed" : "pkg changed");
18130                                    }
18131                                    final int cmd = killProcess
18132                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18133                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18134                                    sendPackageBroadcastLocked(cmd,
18135                                            new String[] {ssp}, userId);
18136                                    if (fullUninstall) {
18137                                        mAppOpsService.packageRemoved(
18138                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18139
18140                                        // Remove all permissions granted from/to this package
18141                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18142
18143                                        removeTasksByPackageNameLocked(ssp, userId);
18144
18145                                        // Hide the "unsupported display" dialog if necessary.
18146                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18147                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18148                                            mUnsupportedDisplaySizeDialog.dismiss();
18149                                            mUnsupportedDisplaySizeDialog = null;
18150                                        }
18151                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18152                                        mBatteryStatsService.notePackageUninstalled(ssp);
18153                                    }
18154                                } else {
18155                                    if (killProcess) {
18156                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18157                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18158                                                userId, ProcessList.INVALID_ADJ,
18159                                                false, true, true, false, "change " + ssp);
18160                                    }
18161                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18162                                            intent.getStringArrayExtra(
18163                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18164                                }
18165                            }
18166                            break;
18167                        case Intent.ACTION_PACKAGES_SUSPENDED:
18168                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18169                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18170                                    intent.getAction());
18171                            final String[] packageNames = intent.getStringArrayExtra(
18172                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18173                            final int userHandle = intent.getIntExtra(
18174                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18175
18176                            synchronized(ActivityManagerService.this) {
18177                                mRecentTasks.onPackagesSuspendedChanged(
18178                                        packageNames, suspended, userHandle);
18179                            }
18180                            break;
18181                    }
18182                    break;
18183                case Intent.ACTION_PACKAGE_REPLACED:
18184                {
18185                    final Uri data = intent.getData();
18186                    final String ssp;
18187                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18188                        final ApplicationInfo aInfo =
18189                                getPackageManagerInternalLocked().getApplicationInfo(
18190                                        ssp,
18191                                        userId);
18192                        if (aInfo == null) {
18193                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18194                                    + " ssp=" + ssp + " data=" + data);
18195                            return ActivityManager.BROADCAST_SUCCESS;
18196                        }
18197                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18198                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18199                                new String[] {ssp}, userId);
18200                    }
18201                    break;
18202                }
18203                case Intent.ACTION_PACKAGE_ADDED:
18204                {
18205                    // Special case for adding a package: by default turn on compatibility mode.
18206                    Uri data = intent.getData();
18207                    String ssp;
18208                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18209                        final boolean replacing =
18210                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18211                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18212
18213                        try {
18214                            ApplicationInfo ai = AppGlobals.getPackageManager().
18215                                    getApplicationInfo(ssp, 0, 0);
18216                            mBatteryStatsService.notePackageInstalled(ssp,
18217                                    ai != null ? ai.versionCode : 0);
18218                        } catch (RemoteException e) {
18219                        }
18220                    }
18221                    break;
18222                }
18223                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18224                {
18225                    Uri data = intent.getData();
18226                    String ssp;
18227                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18228                        // Hide the "unsupported display" dialog if necessary.
18229                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18230                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18231                            mUnsupportedDisplaySizeDialog.dismiss();
18232                            mUnsupportedDisplaySizeDialog = null;
18233                        }
18234                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18235                    }
18236                    break;
18237                }
18238                case Intent.ACTION_TIMEZONE_CHANGED:
18239                    // If this is the time zone changed action, queue up a message that will reset
18240                    // the timezone of all currently running processes. This message will get
18241                    // queued up before the broadcast happens.
18242                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18243                    break;
18244                case Intent.ACTION_TIME_CHANGED:
18245                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18246                    // the tri-state value it may contain and "unknown".
18247                    // For convenience we re-use the Intent extra values.
18248                    final int NO_EXTRA_VALUE_FOUND = -1;
18249                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18250                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18251                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18252                    // Only send a message if the time preference is available.
18253                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18254                        Message updateTimePreferenceMsg =
18255                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18256                                        timeFormatPreferenceMsgValue, 0);
18257                        mHandler.sendMessage(updateTimePreferenceMsg);
18258                    }
18259                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18260                    synchronized (stats) {
18261                        stats.noteCurrentTimeChangedLocked();
18262                    }
18263                    break;
18264                case Intent.ACTION_CLEAR_DNS_CACHE:
18265                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18266                    break;
18267                case Proxy.PROXY_CHANGE_ACTION:
18268                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18269                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18270                    break;
18271                case android.hardware.Camera.ACTION_NEW_PICTURE:
18272                case android.hardware.Camera.ACTION_NEW_VIDEO:
18273                    // These broadcasts are no longer allowed by the system, since they can
18274                    // cause significant thrashing at a crictical point (using the camera).
18275                    // Apps should use JobScehduler to monitor for media provider changes.
18276                    Slog.w(TAG, action + " no longer allowed; dropping from "
18277                            + UserHandle.formatUid(callingUid));
18278                    if (resultTo != null) {
18279                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18280                        try {
18281                            queue.performReceiveLocked(callerApp, resultTo, intent,
18282                                    Activity.RESULT_CANCELED, null, null,
18283                                    false, false, userId);
18284                        } catch (RemoteException e) {
18285                            Slog.w(TAG, "Failure ["
18286                                    + queue.mQueueName + "] sending broadcast result of "
18287                                    + intent, e);
18288
18289                        }
18290                    }
18291                    // Lie; we don't want to crash the app.
18292                    return ActivityManager.BROADCAST_SUCCESS;
18293                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18294                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18295                    break;
18296            }
18297        }
18298
18299        // Add to the sticky list if requested.
18300        if (sticky) {
18301            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18302                    callingPid, callingUid)
18303                    != PackageManager.PERMISSION_GRANTED) {
18304                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18305                        + callingPid + ", uid=" + callingUid
18306                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18307                Slog.w(TAG, msg);
18308                throw new SecurityException(msg);
18309            }
18310            if (requiredPermissions != null && requiredPermissions.length > 0) {
18311                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18312                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18313                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18314            }
18315            if (intent.getComponent() != null) {
18316                throw new SecurityException(
18317                        "Sticky broadcasts can't target a specific component");
18318            }
18319            // We use userId directly here, since the "all" target is maintained
18320            // as a separate set of sticky broadcasts.
18321            if (userId != UserHandle.USER_ALL) {
18322                // But first, if this is not a broadcast to all users, then
18323                // make sure it doesn't conflict with an existing broadcast to
18324                // all users.
18325                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18326                        UserHandle.USER_ALL);
18327                if (stickies != null) {
18328                    ArrayList<Intent> list = stickies.get(intent.getAction());
18329                    if (list != null) {
18330                        int N = list.size();
18331                        int i;
18332                        for (i=0; i<N; i++) {
18333                            if (intent.filterEquals(list.get(i))) {
18334                                throw new IllegalArgumentException(
18335                                        "Sticky broadcast " + intent + " for user "
18336                                        + userId + " conflicts with existing global broadcast");
18337                            }
18338                        }
18339                    }
18340                }
18341            }
18342            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18343            if (stickies == null) {
18344                stickies = new ArrayMap<>();
18345                mStickyBroadcasts.put(userId, stickies);
18346            }
18347            ArrayList<Intent> list = stickies.get(intent.getAction());
18348            if (list == null) {
18349                list = new ArrayList<>();
18350                stickies.put(intent.getAction(), list);
18351            }
18352            final int stickiesCount = list.size();
18353            int i;
18354            for (i = 0; i < stickiesCount; i++) {
18355                if (intent.filterEquals(list.get(i))) {
18356                    // This sticky already exists, replace it.
18357                    list.set(i, new Intent(intent));
18358                    break;
18359                }
18360            }
18361            if (i >= stickiesCount) {
18362                list.add(new Intent(intent));
18363            }
18364        }
18365
18366        int[] users;
18367        if (userId == UserHandle.USER_ALL) {
18368            // Caller wants broadcast to go to all started users.
18369            users = mUserController.getStartedUserArrayLocked();
18370        } else {
18371            // Caller wants broadcast to go to one specific user.
18372            users = new int[] {userId};
18373        }
18374
18375        // Figure out who all will receive this broadcast.
18376        List receivers = null;
18377        List<BroadcastFilter> registeredReceivers = null;
18378        // Need to resolve the intent to interested receivers...
18379        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18380                 == 0) {
18381            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18382        }
18383        if (intent.getComponent() == null) {
18384            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18385                // Query one target user at a time, excluding shell-restricted users
18386                for (int i = 0; i < users.length; i++) {
18387                    if (mUserController.hasUserRestriction(
18388                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18389                        continue;
18390                    }
18391                    List<BroadcastFilter> registeredReceiversForUser =
18392                            mReceiverResolver.queryIntent(intent,
18393                                    resolvedType, false, false /*visibleToEphemeral*/,
18394                                    false /*isEphemeral*/, users[i]);
18395                    if (registeredReceivers == null) {
18396                        registeredReceivers = registeredReceiversForUser;
18397                    } else if (registeredReceiversForUser != null) {
18398                        registeredReceivers.addAll(registeredReceiversForUser);
18399                    }
18400                }
18401            } else {
18402                registeredReceivers = mReceiverResolver.queryIntent(intent,
18403                        resolvedType, false, false /*visibleToEphemeral*/,
18404                        false /*isEphemeral*/, userId);
18405            }
18406        }
18407
18408        final boolean replacePending =
18409                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18410
18411        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18412                + " replacePending=" + replacePending);
18413
18414        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18415        if (!ordered && NR > 0) {
18416            // If we are not serializing this broadcast, then send the
18417            // registered receivers separately so they don't wait for the
18418            // components to be launched.
18419            if (isCallerSystem) {
18420                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18421                        isProtectedBroadcast, registeredReceivers);
18422            }
18423            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18424            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18425                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18426                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18427                    resultExtras, ordered, sticky, false, userId);
18428            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18429            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18430            if (!replaced) {
18431                queue.enqueueParallelBroadcastLocked(r);
18432                queue.scheduleBroadcastsLocked();
18433            }
18434            registeredReceivers = null;
18435            NR = 0;
18436        }
18437
18438        // Merge into one list.
18439        int ir = 0;
18440        if (receivers != null) {
18441            // A special case for PACKAGE_ADDED: do not allow the package
18442            // being added to see this broadcast.  This prevents them from
18443            // using this as a back door to get run as soon as they are
18444            // installed.  Maybe in the future we want to have a special install
18445            // broadcast or such for apps, but we'd like to deliberately make
18446            // this decision.
18447            String skipPackages[] = null;
18448            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18449                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18450                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18451                Uri data = intent.getData();
18452                if (data != null) {
18453                    String pkgName = data.getSchemeSpecificPart();
18454                    if (pkgName != null) {
18455                        skipPackages = new String[] { pkgName };
18456                    }
18457                }
18458            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18459                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18460            }
18461            if (skipPackages != null && (skipPackages.length > 0)) {
18462                for (String skipPackage : skipPackages) {
18463                    if (skipPackage != null) {
18464                        int NT = receivers.size();
18465                        for (int it=0; it<NT; it++) {
18466                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18467                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18468                                receivers.remove(it);
18469                                it--;
18470                                NT--;
18471                            }
18472                        }
18473                    }
18474                }
18475            }
18476
18477            int NT = receivers != null ? receivers.size() : 0;
18478            int it = 0;
18479            ResolveInfo curt = null;
18480            BroadcastFilter curr = null;
18481            while (it < NT && ir < NR) {
18482                if (curt == null) {
18483                    curt = (ResolveInfo)receivers.get(it);
18484                }
18485                if (curr == null) {
18486                    curr = registeredReceivers.get(ir);
18487                }
18488                if (curr.getPriority() >= curt.priority) {
18489                    // Insert this broadcast record into the final list.
18490                    receivers.add(it, curr);
18491                    ir++;
18492                    curr = null;
18493                    it++;
18494                    NT++;
18495                } else {
18496                    // Skip to the next ResolveInfo in the final list.
18497                    it++;
18498                    curt = null;
18499                }
18500            }
18501        }
18502        while (ir < NR) {
18503            if (receivers == null) {
18504                receivers = new ArrayList();
18505            }
18506            receivers.add(registeredReceivers.get(ir));
18507            ir++;
18508        }
18509
18510        if (isCallerSystem) {
18511            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18512                    isProtectedBroadcast, receivers);
18513        }
18514
18515        if ((receivers != null && receivers.size() > 0)
18516                || resultTo != null) {
18517            BroadcastQueue queue = broadcastQueueForIntent(intent);
18518            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18519                    callerPackage, callingPid, callingUid, resolvedType,
18520                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18521                    resultData, resultExtras, ordered, sticky, false, userId);
18522
18523            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18524                    + ": prev had " + queue.mOrderedBroadcasts.size());
18525            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18526                    "Enqueueing broadcast " + r.intent.getAction());
18527
18528            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18529            if (!replaced) {
18530                queue.enqueueOrderedBroadcastLocked(r);
18531                queue.scheduleBroadcastsLocked();
18532            }
18533        } else {
18534            // There was nobody interested in the broadcast, but we still want to record
18535            // that it happened.
18536            if (intent.getComponent() == null && intent.getPackage() == null
18537                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18538                // This was an implicit broadcast... let's record it for posterity.
18539                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18540            }
18541        }
18542
18543        return ActivityManager.BROADCAST_SUCCESS;
18544    }
18545
18546    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18547            int skipCount, long dispatchTime) {
18548        final long now = SystemClock.elapsedRealtime();
18549        if (mCurBroadcastStats == null ||
18550                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18551            mLastBroadcastStats = mCurBroadcastStats;
18552            if (mLastBroadcastStats != null) {
18553                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18554                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18555            }
18556            mCurBroadcastStats = new BroadcastStats();
18557        }
18558        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18559    }
18560
18561    final Intent verifyBroadcastLocked(Intent intent) {
18562        // Refuse possible leaked file descriptors
18563        if (intent != null && intent.hasFileDescriptors() == true) {
18564            throw new IllegalArgumentException("File descriptors passed in Intent");
18565        }
18566
18567        int flags = intent.getFlags();
18568
18569        if (!mProcessesReady) {
18570            // if the caller really truly claims to know what they're doing, go
18571            // ahead and allow the broadcast without launching any receivers
18572            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18573                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18574            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18575                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18576                        + " before boot completion");
18577                throw new IllegalStateException("Cannot broadcast before boot completed");
18578            }
18579        }
18580
18581        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18582            throw new IllegalArgumentException(
18583                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18584        }
18585
18586        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18587            switch (Binder.getCallingUid()) {
18588                case Process.ROOT_UID:
18589                case Process.SHELL_UID:
18590                    break;
18591                default:
18592                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
18593                            + Binder.getCallingUid());
18594                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
18595                    break;
18596            }
18597        }
18598
18599        return intent;
18600    }
18601
18602    public final int broadcastIntent(IApplicationThread caller,
18603            Intent intent, String resolvedType, IIntentReceiver resultTo,
18604            int resultCode, String resultData, Bundle resultExtras,
18605            String[] requiredPermissions, int appOp, Bundle bOptions,
18606            boolean serialized, boolean sticky, int userId) {
18607        enforceNotIsolatedCaller("broadcastIntent");
18608        synchronized(this) {
18609            intent = verifyBroadcastLocked(intent);
18610
18611            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18612            final int callingPid = Binder.getCallingPid();
18613            final int callingUid = Binder.getCallingUid();
18614            final long origId = Binder.clearCallingIdentity();
18615            int res = broadcastIntentLocked(callerApp,
18616                    callerApp != null ? callerApp.info.packageName : null,
18617                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18618                    requiredPermissions, appOp, bOptions, serialized, sticky,
18619                    callingPid, callingUid, userId);
18620            Binder.restoreCallingIdentity(origId);
18621            return res;
18622        }
18623    }
18624
18625
18626    int broadcastIntentInPackage(String packageName, int uid,
18627            Intent intent, String resolvedType, IIntentReceiver resultTo,
18628            int resultCode, String resultData, Bundle resultExtras,
18629            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18630            int userId) {
18631        synchronized(this) {
18632            intent = verifyBroadcastLocked(intent);
18633
18634            final long origId = Binder.clearCallingIdentity();
18635            String[] requiredPermissions = requiredPermission == null ? null
18636                    : new String[] {requiredPermission};
18637            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18638                    resultTo, resultCode, resultData, resultExtras,
18639                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18640                    sticky, -1, uid, userId);
18641            Binder.restoreCallingIdentity(origId);
18642            return res;
18643        }
18644    }
18645
18646    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18647        // Refuse possible leaked file descriptors
18648        if (intent != null && intent.hasFileDescriptors() == true) {
18649            throw new IllegalArgumentException("File descriptors passed in Intent");
18650        }
18651
18652        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18653                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18654
18655        synchronized(this) {
18656            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18657                    != PackageManager.PERMISSION_GRANTED) {
18658                String msg = "Permission Denial: unbroadcastIntent() from pid="
18659                        + Binder.getCallingPid()
18660                        + ", uid=" + Binder.getCallingUid()
18661                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18662                Slog.w(TAG, msg);
18663                throw new SecurityException(msg);
18664            }
18665            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18666            if (stickies != null) {
18667                ArrayList<Intent> list = stickies.get(intent.getAction());
18668                if (list != null) {
18669                    int N = list.size();
18670                    int i;
18671                    for (i=0; i<N; i++) {
18672                        if (intent.filterEquals(list.get(i))) {
18673                            list.remove(i);
18674                            break;
18675                        }
18676                    }
18677                    if (list.size() <= 0) {
18678                        stickies.remove(intent.getAction());
18679                    }
18680                }
18681                if (stickies.size() <= 0) {
18682                    mStickyBroadcasts.remove(userId);
18683                }
18684            }
18685        }
18686    }
18687
18688    void backgroundServicesFinishedLocked(int userId) {
18689        for (BroadcastQueue queue : mBroadcastQueues) {
18690            queue.backgroundServicesFinishedLocked(userId);
18691        }
18692    }
18693
18694    public void finishReceiver(IBinder who, int resultCode, String resultData,
18695            Bundle resultExtras, boolean resultAbort, int flags) {
18696        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18697
18698        // Refuse possible leaked file descriptors
18699        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18700            throw new IllegalArgumentException("File descriptors passed in Bundle");
18701        }
18702
18703        final long origId = Binder.clearCallingIdentity();
18704        try {
18705            boolean doNext = false;
18706            BroadcastRecord r;
18707
18708            synchronized(this) {
18709                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18710                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18711                r = queue.getMatchingOrderedReceiver(who);
18712                if (r != null) {
18713                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18714                        resultData, resultExtras, resultAbort, true);
18715                }
18716            }
18717
18718            if (doNext) {
18719                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
18720                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
18721                      String.format("ProcessBroadcast from %s (%s) %s", r.callerPackage,
18722                        r.callerApp == null ? "caller unknown" : r.callerApp.toShortString(),
18723                        r.intent == null ? "" : r.intent.toString()));
18724                }
18725                r.queue.processNextBroadcast(false);
18726                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
18727            }
18728            trimApplications();
18729        } finally {
18730            Binder.restoreCallingIdentity(origId);
18731        }
18732    }
18733
18734    // =========================================================
18735    // INSTRUMENTATION
18736    // =========================================================
18737
18738    public boolean startInstrumentation(ComponentName className,
18739            String profileFile, int flags, Bundle arguments,
18740            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18741            int userId, String abiOverride) {
18742        enforceNotIsolatedCaller("startInstrumentation");
18743        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18744                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18745        // Refuse possible leaked file descriptors
18746        if (arguments != null && arguments.hasFileDescriptors()) {
18747            throw new IllegalArgumentException("File descriptors passed in Bundle");
18748        }
18749
18750        synchronized(this) {
18751            InstrumentationInfo ii = null;
18752            ApplicationInfo ai = null;
18753            try {
18754                ii = mContext.getPackageManager().getInstrumentationInfo(
18755                    className, STOCK_PM_FLAGS);
18756                ai = AppGlobals.getPackageManager().getApplicationInfo(
18757                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18758            } catch (PackageManager.NameNotFoundException e) {
18759            } catch (RemoteException e) {
18760            }
18761            if (ii == null) {
18762                reportStartInstrumentationFailureLocked(watcher, className,
18763                        "Unable to find instrumentation info for: " + className);
18764                return false;
18765            }
18766            if (ai == null) {
18767                reportStartInstrumentationFailureLocked(watcher, className,
18768                        "Unable to find instrumentation target package: " + ii.targetPackage);
18769                return false;
18770            }
18771            if (!ai.hasCode()) {
18772                reportStartInstrumentationFailureLocked(watcher, className,
18773                        "Instrumentation target has no code: " + ii.targetPackage);
18774                return false;
18775            }
18776
18777            int match = mContext.getPackageManager().checkSignatures(
18778                    ii.targetPackage, ii.packageName);
18779            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18780                String msg = "Permission Denial: starting instrumentation "
18781                        + className + " from pid="
18782                        + Binder.getCallingPid()
18783                        + ", uid=" + Binder.getCallingPid()
18784                        + " not allowed because package " + ii.packageName
18785                        + " does not have a signature matching the target "
18786                        + ii.targetPackage;
18787                reportStartInstrumentationFailureLocked(watcher, className, msg);
18788                throw new SecurityException(msg);
18789            }
18790
18791            final long origId = Binder.clearCallingIdentity();
18792            // Instrumentation can kill and relaunch even persistent processes
18793            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18794                    "start instr");
18795            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18796            app.instrumentationClass = className;
18797            app.instrumentationInfo = ai;
18798            app.instrumentationProfileFile = profileFile;
18799            app.instrumentationArguments = arguments;
18800            app.instrumentationWatcher = watcher;
18801            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18802            app.instrumentationResultClass = className;
18803            Binder.restoreCallingIdentity(origId);
18804        }
18805
18806        return true;
18807    }
18808
18809    /**
18810     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18811     * error to the logs, but if somebody is watching, send the report there too.  This enables
18812     * the "am" command to report errors with more information.
18813     *
18814     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18815     * @param cn The component name of the instrumentation.
18816     * @param report The error report.
18817     */
18818    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18819            ComponentName cn, String report) {
18820        Slog.w(TAG, report);
18821        if (watcher != null) {
18822            Bundle results = new Bundle();
18823            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18824            results.putString("Error", report);
18825            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18826        }
18827    }
18828
18829    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18830        if (app.instrumentationWatcher != null) {
18831            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18832                    app.instrumentationClass, resultCode, results);
18833        }
18834
18835        // Can't call out of the system process with a lock held, so post a message.
18836        if (app.instrumentationUiAutomationConnection != null) {
18837            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18838                    app.instrumentationUiAutomationConnection).sendToTarget();
18839        }
18840
18841        app.instrumentationWatcher = null;
18842        app.instrumentationUiAutomationConnection = null;
18843        app.instrumentationClass = null;
18844        app.instrumentationInfo = null;
18845        app.instrumentationProfileFile = null;
18846        app.instrumentationArguments = null;
18847
18848        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18849                "finished inst");
18850    }
18851
18852    public void finishInstrumentation(IApplicationThread target,
18853            int resultCode, Bundle results) {
18854        int userId = UserHandle.getCallingUserId();
18855        // Refuse possible leaked file descriptors
18856        if (results != null && results.hasFileDescriptors()) {
18857            throw new IllegalArgumentException("File descriptors passed in Intent");
18858        }
18859
18860        synchronized(this) {
18861            ProcessRecord app = getRecordForAppLocked(target);
18862            if (app == null) {
18863                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18864                return;
18865            }
18866            final long origId = Binder.clearCallingIdentity();
18867            finishInstrumentationLocked(app, resultCode, results);
18868            Binder.restoreCallingIdentity(origId);
18869        }
18870    }
18871
18872    // =========================================================
18873    // CONFIGURATION
18874    // =========================================================
18875
18876    public ConfigurationInfo getDeviceConfigurationInfo() {
18877        ConfigurationInfo config = new ConfigurationInfo();
18878        synchronized (this) {
18879            final Configuration globalConfig = getGlobalConfiguration();
18880            config.reqTouchScreen = globalConfig.touchscreen;
18881            config.reqKeyboardType = globalConfig.keyboard;
18882            config.reqNavigation = globalConfig.navigation;
18883            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18884                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18885                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18886            }
18887            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18888                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18889                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18890            }
18891            config.reqGlEsVersion = GL_ES_VERSION;
18892        }
18893        return config;
18894    }
18895
18896    ActivityStack getFocusedStack() {
18897        return mStackSupervisor.getFocusedStack();
18898    }
18899
18900    @Override
18901    public int getFocusedStackId() throws RemoteException {
18902        ActivityStack focusedStack = getFocusedStack();
18903        if (focusedStack != null) {
18904            return focusedStack.getStackId();
18905        }
18906        return -1;
18907    }
18908
18909    public Configuration getConfiguration() {
18910        Configuration ci;
18911        synchronized(this) {
18912            ci = new Configuration(getGlobalConfiguration());
18913            ci.userSetLocale = false;
18914        }
18915        return ci;
18916    }
18917
18918    @Override
18919    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18920        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18921        synchronized (this) {
18922            mSuppressResizeConfigChanges = suppress;
18923        }
18924    }
18925
18926    @Override
18927    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18928        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18929        if (StackId.isHomeOrRecentsStack(fromStackId)) {
18930            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
18931        }
18932        synchronized (this) {
18933            final long origId = Binder.clearCallingIdentity();
18934            try {
18935                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18936            } finally {
18937                Binder.restoreCallingIdentity(origId);
18938            }
18939        }
18940    }
18941
18942    @Override
18943    public void updatePersistentConfiguration(Configuration values) {
18944        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
18945        enforceWriteSettingsPermission("updatePersistentConfiguration()");
18946        if (values == null) {
18947            throw new NullPointerException("Configuration must not be null");
18948        }
18949
18950        int userId = UserHandle.getCallingUserId();
18951
18952        synchronized(this) {
18953            updatePersistentConfigurationLocked(values, userId);
18954        }
18955    }
18956
18957    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18958        final long origId = Binder.clearCallingIdentity();
18959        try {
18960            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18961        } finally {
18962            Binder.restoreCallingIdentity(origId);
18963        }
18964    }
18965
18966    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18967        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18968                FONT_SCALE, 1.0f, userId);
18969
18970        synchronized (this) {
18971            if (getGlobalConfiguration().fontScale == scaleFactor) {
18972                return;
18973            }
18974
18975            final Configuration configuration
18976                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18977            configuration.fontScale = scaleFactor;
18978            updatePersistentConfigurationLocked(configuration, userId);
18979        }
18980    }
18981
18982    private void enforceWriteSettingsPermission(String func) {
18983        int uid = Binder.getCallingUid();
18984        if (uid == Process.ROOT_UID) {
18985            return;
18986        }
18987
18988        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18989                Settings.getPackageNameForUid(mContext, uid), false)) {
18990            return;
18991        }
18992
18993        String msg = "Permission Denial: " + func + " from pid="
18994                + Binder.getCallingPid()
18995                + ", uid=" + uid
18996                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18997        Slog.w(TAG, msg);
18998        throw new SecurityException(msg);
18999    }
19000
19001    @Override
19002    public boolean updateConfiguration(Configuration values) {
19003        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19004
19005        synchronized(this) {
19006            if (values == null && mWindowManager != null) {
19007                // sentinel: fetch the current configuration from the window manager
19008                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19009            }
19010
19011            if (mWindowManager != null) {
19012                // Update OOM levels based on display size.
19013                mProcessList.applyDisplaySize(mWindowManager);
19014            }
19015
19016            final long origId = Binder.clearCallingIdentity();
19017            try {
19018                if (values != null) {
19019                    Settings.System.clearConfiguration(values);
19020                }
19021                updateConfigurationLocked(values, null, false, false /* persistent */,
19022                        UserHandle.USER_NULL, false /* deferResume */,
19023                        mTmpUpdateConfigurationResult);
19024                return mTmpUpdateConfigurationResult.changes != 0;
19025            } finally {
19026                Binder.restoreCallingIdentity(origId);
19027            }
19028        }
19029    }
19030
19031    void updateUserConfigurationLocked() {
19032        final Configuration configuration = new Configuration(getGlobalConfiguration());
19033        final int currentUserId = mUserController.getCurrentUserIdLocked();
19034        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19035                currentUserId, Settings.System.canWrite(mContext));
19036        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19037                false /* persistent */, currentUserId, false /* deferResume */);
19038    }
19039
19040    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19041            boolean initLocale) {
19042        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19043    }
19044
19045    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19046            boolean initLocale, boolean deferResume) {
19047        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19048        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19049                UserHandle.USER_NULL, deferResume);
19050    }
19051
19052    // To cache the list of supported system locales
19053    private String[] mSupportedSystemLocales = null;
19054
19055    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19056            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19057        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19058                deferResume, null /* result */);
19059    }
19060
19061    /**
19062     * Do either or both things: (1) change the current configuration, and (2)
19063     * make sure the given activity is running with the (now) current
19064     * configuration.  Returns true if the activity has been left running, or
19065     * false if <var>starting</var> is being destroyed to match the new
19066     * configuration.
19067     *
19068     * @param userId is only used when persistent parameter is set to true to persist configuration
19069     *               for that particular user
19070     */
19071    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19072            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19073            UpdateConfigurationResult result) {
19074        int changes = 0;
19075        boolean kept = true;
19076
19077        if (mWindowManager != null) {
19078            mWindowManager.deferSurfaceLayout();
19079        }
19080        try {
19081            if (values != null) {
19082                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19083                        deferResume);
19084            }
19085
19086            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19087        } finally {
19088            if (mWindowManager != null) {
19089                mWindowManager.continueSurfaceLayout();
19090            }
19091        }
19092
19093        if (result != null) {
19094            result.changes = changes;
19095            result.activityRelaunched = !kept;
19096        }
19097        return kept;
19098    }
19099
19100    /** Update default (global) configuration and notify listeners about changes. */
19101    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19102            boolean persistent, int userId, boolean deferResume) {
19103        mTempConfig.setTo(getGlobalConfiguration());
19104        final int changes = mTempConfig.updateFrom(values);
19105        if (changes == 0) {
19106            return 0;
19107        }
19108
19109        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19110                "Updating global configuration to: " + values);
19111
19112        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19113
19114        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19115            final LocaleList locales = values.getLocales();
19116            int bestLocaleIndex = 0;
19117            if (locales.size() > 1) {
19118                if (mSupportedSystemLocales == null) {
19119                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19120                }
19121                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19122            }
19123            SystemProperties.set("persist.sys.locale",
19124                    locales.get(bestLocaleIndex).toLanguageTag());
19125            LocaleList.setDefault(locales, bestLocaleIndex);
19126            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19127                    locales.get(bestLocaleIndex)));
19128        }
19129
19130        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19131        mTempConfig.seq = mConfigurationSeq;
19132
19133        // Update stored global config and notify everyone about the change.
19134        mStackSupervisor.onConfigurationChanged(mTempConfig);
19135
19136        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19137        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19138        mUsageStatsService.reportConfigurationChange(mTempConfig,
19139                mUserController.getCurrentUserIdLocked());
19140
19141        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19142        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
19143
19144        AttributeCache ac = AttributeCache.instance();
19145        if (ac != null) {
19146            ac.updateConfiguration(mTempConfig);
19147        }
19148
19149        // Make sure all resources in our process are updated right now, so that anyone who is going
19150        // to retrieve resource values after we return will be sure to get the new ones. This is
19151        // especially important during boot, where the first config change needs to guarantee all
19152        // resources have that config before following boot code is executed.
19153        mSystemThread.applyConfigurationToResources(mTempConfig);
19154
19155        // We need another copy of global config because we're scheduling some calls instead of
19156        // running them in place. We need to be sure that object we send will be handled unchanged.
19157        final Configuration configCopy = new Configuration(mTempConfig);
19158        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19159            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19160            msg.obj = configCopy;
19161            msg.arg1 = userId;
19162            mHandler.sendMessage(msg);
19163        }
19164
19165        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19166            ProcessRecord app = mLruProcesses.get(i);
19167            try {
19168                if (app.thread != null) {
19169                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19170                            + app.processName + " new config " + configCopy);
19171                    app.thread.scheduleConfigurationChanged(configCopy);
19172                }
19173            } catch (Exception e) {
19174            }
19175        }
19176
19177        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19178        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19179                | Intent.FLAG_RECEIVER_FOREGROUND);
19180        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19181                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19182                UserHandle.USER_ALL);
19183        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19184            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19185            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19186            if (initLocale || !mProcessesReady) {
19187                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19188            }
19189            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19190                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19191                    UserHandle.USER_ALL);
19192        }
19193
19194        // Override configuration of the default display duplicates global config, so we need to
19195        // update it also. This will also notify WindowManager about changes.
19196        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19197                DEFAULT_DISPLAY);
19198
19199        return changes;
19200    }
19201
19202    @Override
19203    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19204        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19205
19206        synchronized (this) {
19207            // Check if display is initialized in AM.
19208            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19209                // Call might come when display is not yet added or has already been removed.
19210                if (DEBUG_CONFIGURATION) {
19211                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19212                            + displayId);
19213                }
19214                return false;
19215            }
19216
19217            if (values == null && mWindowManager != null) {
19218                // sentinel: fetch the current configuration from the window manager
19219                values = mWindowManager.computeNewConfiguration(displayId);
19220            }
19221
19222            if (mWindowManager != null) {
19223                // Update OOM levels based on display size.
19224                mProcessList.applyDisplaySize(mWindowManager);
19225            }
19226
19227            final long origId = Binder.clearCallingIdentity();
19228            try {
19229                if (values != null) {
19230                    Settings.System.clearConfiguration(values);
19231                }
19232                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19233                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19234                return mTmpUpdateConfigurationResult.changes != 0;
19235            } finally {
19236                Binder.restoreCallingIdentity(origId);
19237            }
19238        }
19239    }
19240
19241    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19242            boolean deferResume, int displayId) {
19243        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19244                displayId, null /* result */);
19245    }
19246
19247    /**
19248     * Updates override configuration specific for the selected display. If no config is provided,
19249     * new one will be computed in WM based on current display info.
19250     */
19251    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19252            ActivityRecord starting, boolean deferResume, int displayId,
19253            UpdateConfigurationResult result) {
19254        int changes = 0;
19255        boolean kept = true;
19256
19257        if (mWindowManager != null) {
19258            mWindowManager.deferSurfaceLayout();
19259        }
19260        try {
19261            if (values != null) {
19262                if (displayId == DEFAULT_DISPLAY) {
19263                    // Override configuration of the default display duplicates global config, so
19264                    // we're calling global config update instead for default display. It will also
19265                    // apply the correct override config.
19266                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19267                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19268                } else {
19269                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19270                }
19271            }
19272
19273            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19274        } finally {
19275            if (mWindowManager != null) {
19276                mWindowManager.continueSurfaceLayout();
19277            }
19278        }
19279
19280        if (result != null) {
19281            result.changes = changes;
19282            result.activityRelaunched = !kept;
19283        }
19284        return kept;
19285    }
19286
19287    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19288            int displayId) {
19289        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19290        final int changes = mTempConfig.updateFrom(values);
19291        if (changes == 0) {
19292            return 0;
19293        }
19294
19295        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19296                + " for displayId=" + displayId);
19297        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19298
19299        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19300        if (isDensityChange) {
19301            // Reset the unsupported display size dialog.
19302            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19303
19304            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19305        }
19306
19307        // Update the configuration with WM first and check if any of the stacks need to be resized
19308        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19309        // necessary. This way we don't need to relaunch again afterwards in
19310        // ensureActivityConfigurationLocked().
19311        if (mWindowManager != null) {
19312            final int[] resizedStacks =
19313                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19314            if (resizedStacks != null) {
19315                for (int stackId : resizedStacks) {
19316                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19317                }
19318            }
19319        }
19320
19321        return changes;
19322    }
19323
19324    /** Applies latest configuration and/or visibility updates if needed. */
19325    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19326        boolean kept = true;
19327        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19328        // mainStack is null during startup.
19329        if (mainStack != null) {
19330            if (changes != 0 && starting == null) {
19331                // If the configuration changed, and the caller is not already
19332                // in the process of starting an activity, then find the top
19333                // activity to check if its configuration needs to change.
19334                starting = mainStack.topRunningActivityLocked();
19335            }
19336
19337            if (starting != null) {
19338                kept = starting.ensureActivityConfigurationLocked(changes,
19339                        false /* preserveWindow */);
19340                // And we need to make sure at this point that all other activities
19341                // are made visible with the correct configuration.
19342                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19343                        !PRESERVE_WINDOWS);
19344            }
19345        }
19346
19347        return kept;
19348    }
19349
19350    /** Helper method that requests bounds from WM and applies them to stack. */
19351    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19352        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19353        mStackSupervisor.resizeStackLocked(
19354                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19355                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19356    }
19357
19358    /**
19359     * Decide based on the configuration whether we should show the ANR,
19360     * crash, etc dialogs.  The idea is that if there is no affordance to
19361     * press the on-screen buttons, or the user experience would be more
19362     * greatly impacted than the crash itself, we shouldn't show the dialog.
19363     *
19364     * A thought: SystemUI might also want to get told about this, the Power
19365     * dialog / global actions also might want different behaviors.
19366     */
19367    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19368        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19369                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19370                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19371        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19372        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19373                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19374        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19375    }
19376
19377    @Override
19378    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19379        synchronized (this) {
19380            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19381            if (srec != null) {
19382                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19383            }
19384        }
19385        return false;
19386    }
19387
19388    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19389            Intent resultData) {
19390
19391        synchronized (this) {
19392            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19393            if (r != null) {
19394                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19395            }
19396            return false;
19397        }
19398    }
19399
19400    public int getLaunchedFromUid(IBinder activityToken) {
19401        ActivityRecord srec;
19402        synchronized (this) {
19403            srec = ActivityRecord.forTokenLocked(activityToken);
19404        }
19405        if (srec == null) {
19406            return -1;
19407        }
19408        return srec.launchedFromUid;
19409    }
19410
19411    public String getLaunchedFromPackage(IBinder activityToken) {
19412        ActivityRecord srec;
19413        synchronized (this) {
19414            srec = ActivityRecord.forTokenLocked(activityToken);
19415        }
19416        if (srec == null) {
19417            return null;
19418        }
19419        return srec.launchedFromPackage;
19420    }
19421
19422    // =========================================================
19423    // LIFETIME MANAGEMENT
19424    // =========================================================
19425
19426    // Returns whether the app is receiving broadcast.
19427    // If receiving, fetch all broadcast queues which the app is
19428    // the current [or imminent] receiver on.
19429    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19430            ArraySet<BroadcastQueue> receivingQueues) {
19431        if (!app.curReceivers.isEmpty()) {
19432            for (BroadcastRecord r : app.curReceivers) {
19433                receivingQueues.add(r.queue);
19434            }
19435            return true;
19436        }
19437
19438        // It's not the current receiver, but it might be starting up to become one
19439        for (BroadcastQueue queue : mBroadcastQueues) {
19440            final BroadcastRecord r = queue.mPendingBroadcast;
19441            if (r != null && r.curApp == app) {
19442                // found it; report which queue it's in
19443                receivingQueues.add(queue);
19444            }
19445        }
19446
19447        return !receivingQueues.isEmpty();
19448    }
19449
19450    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19451            int targetUid, ComponentName targetComponent, String targetProcess) {
19452        if (!mTrackingAssociations) {
19453            return null;
19454        }
19455        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19456                = mAssociations.get(targetUid);
19457        if (components == null) {
19458            components = new ArrayMap<>();
19459            mAssociations.put(targetUid, components);
19460        }
19461        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19462        if (sourceUids == null) {
19463            sourceUids = new SparseArray<>();
19464            components.put(targetComponent, sourceUids);
19465        }
19466        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19467        if (sourceProcesses == null) {
19468            sourceProcesses = new ArrayMap<>();
19469            sourceUids.put(sourceUid, sourceProcesses);
19470        }
19471        Association ass = sourceProcesses.get(sourceProcess);
19472        if (ass == null) {
19473            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19474                    targetProcess);
19475            sourceProcesses.put(sourceProcess, ass);
19476        }
19477        ass.mCount++;
19478        ass.mNesting++;
19479        if (ass.mNesting == 1) {
19480            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19481            ass.mLastState = sourceState;
19482        }
19483        return ass;
19484    }
19485
19486    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19487            ComponentName targetComponent) {
19488        if (!mTrackingAssociations) {
19489            return;
19490        }
19491        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19492                = mAssociations.get(targetUid);
19493        if (components == null) {
19494            return;
19495        }
19496        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19497        if (sourceUids == null) {
19498            return;
19499        }
19500        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19501        if (sourceProcesses == null) {
19502            return;
19503        }
19504        Association ass = sourceProcesses.get(sourceProcess);
19505        if (ass == null || ass.mNesting <= 0) {
19506            return;
19507        }
19508        ass.mNesting--;
19509        if (ass.mNesting == 0) {
19510            long uptime = SystemClock.uptimeMillis();
19511            ass.mTime += uptime - ass.mStartTime;
19512            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19513                    += uptime - ass.mLastStateUptime;
19514            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19515        }
19516    }
19517
19518    private void noteUidProcessState(final int uid, final int state) {
19519        mBatteryStatsService.noteUidProcessState(uid, state);
19520        if (mTrackingAssociations) {
19521            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19522                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19523                        = mAssociations.valueAt(i1);
19524                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19525                    SparseArray<ArrayMap<String, Association>> sourceUids
19526                            = targetComponents.valueAt(i2);
19527                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19528                    if (sourceProcesses != null) {
19529                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19530                            Association ass = sourceProcesses.valueAt(i4);
19531                            if (ass.mNesting >= 1) {
19532                                // currently associated
19533                                long uptime = SystemClock.uptimeMillis();
19534                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19535                                        += uptime - ass.mLastStateUptime;
19536                                ass.mLastState = state;
19537                                ass.mLastStateUptime = uptime;
19538                            }
19539                        }
19540                    }
19541                }
19542            }
19543        }
19544    }
19545
19546    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19547            boolean doingAll, long now) {
19548        if (mAdjSeq == app.adjSeq) {
19549            // This adjustment has already been computed.
19550            return app.curRawAdj;
19551        }
19552
19553        if (app.thread == null) {
19554            app.adjSeq = mAdjSeq;
19555            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19556            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19557            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19558        }
19559
19560        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19561        app.adjSource = null;
19562        app.adjTarget = null;
19563        app.empty = false;
19564        app.cached = false;
19565
19566        final int activitiesSize = app.activities.size();
19567
19568        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19569            // The max adjustment doesn't allow this app to be anything
19570            // below foreground, so it is not worth doing work for it.
19571            app.adjType = "fixed";
19572            app.adjSeq = mAdjSeq;
19573            app.curRawAdj = app.maxAdj;
19574            app.foregroundActivities = false;
19575            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19576            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19577            // System processes can do UI, and when they do we want to have
19578            // them trim their memory after the user leaves the UI.  To
19579            // facilitate this, here we need to determine whether or not it
19580            // is currently showing UI.
19581            app.systemNoUi = true;
19582            if (app == TOP_APP) {
19583                app.systemNoUi = false;
19584                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19585                app.adjType = "pers-top-activity";
19586            } else if (app.hasTopUi) {
19587                app.systemNoUi = false;
19588                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19589                app.adjType = "pers-top-ui";
19590            } else if (activitiesSize > 0) {
19591                for (int j = 0; j < activitiesSize; j++) {
19592                    final ActivityRecord r = app.activities.get(j);
19593                    if (r.visible) {
19594                        app.systemNoUi = false;
19595                    }
19596                }
19597            }
19598            if (!app.systemNoUi) {
19599                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19600            }
19601            return (app.curAdj=app.maxAdj);
19602        }
19603
19604        app.systemNoUi = false;
19605
19606        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19607
19608        // Determine the importance of the process, starting with most
19609        // important to least, and assign an appropriate OOM adjustment.
19610        int adj;
19611        int schedGroup;
19612        int procState;
19613        boolean foregroundActivities = false;
19614        mTmpBroadcastQueue.clear();
19615        if (app == TOP_APP) {
19616            // The last app on the list is the foreground app.
19617            adj = ProcessList.FOREGROUND_APP_ADJ;
19618            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19619            app.adjType = "top-activity";
19620            foregroundActivities = true;
19621            procState = PROCESS_STATE_CUR_TOP;
19622        } else if (app.instrumentationClass != null) {
19623            // Don't want to kill running instrumentation.
19624            adj = ProcessList.FOREGROUND_APP_ADJ;
19625            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19626            app.adjType = "instrumentation";
19627            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19628        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
19629            // An app that is currently receiving a broadcast also
19630            // counts as being in the foreground for OOM killer purposes.
19631            // It's placed in a sched group based on the nature of the
19632            // broadcast as reflected by which queue it's active in.
19633            adj = ProcessList.FOREGROUND_APP_ADJ;
19634            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
19635                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19636            app.adjType = "broadcast";
19637            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19638        } else if (app.executingServices.size() > 0) {
19639            // An app that is currently executing a service callback also
19640            // counts as being in the foreground.
19641            adj = ProcessList.FOREGROUND_APP_ADJ;
19642            schedGroup = app.execServicesFg ?
19643                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19644            app.adjType = "exec-service";
19645            procState = ActivityManager.PROCESS_STATE_SERVICE;
19646            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19647        } else {
19648            // As far as we know the process is empty.  We may change our mind later.
19649            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19650            // At this point we don't actually know the adjustment.  Use the cached adj
19651            // value that the caller wants us to.
19652            adj = cachedAdj;
19653            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19654            app.cached = true;
19655            app.empty = true;
19656            app.adjType = "cch-empty";
19657        }
19658
19659        // Examine all activities if not already foreground.
19660        if (!foregroundActivities && activitiesSize > 0) {
19661            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19662            for (int j = 0; j < activitiesSize; j++) {
19663                final ActivityRecord r = app.activities.get(j);
19664                if (r.app != app) {
19665                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19666                            + " instead of expected " + app);
19667                    if (r.app == null || (r.app.uid == app.uid)) {
19668                        // Only fix things up when they look sane
19669                        r.app = app;
19670                    } else {
19671                        continue;
19672                    }
19673                }
19674                if (r.visible) {
19675                    // App has a visible activity; only upgrade adjustment.
19676                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19677                        adj = ProcessList.VISIBLE_APP_ADJ;
19678                        app.adjType = "visible";
19679                    }
19680                    if (procState > PROCESS_STATE_CUR_TOP) {
19681                        procState = PROCESS_STATE_CUR_TOP;
19682                    }
19683                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19684                    app.cached = false;
19685                    app.empty = false;
19686                    foregroundActivities = true;
19687                    if (r.task != null && minLayer > 0) {
19688                        final int layer = r.task.mLayerRank;
19689                        if (layer >= 0 && minLayer > layer) {
19690                            minLayer = layer;
19691                        }
19692                    }
19693                    break;
19694                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19695                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19696                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19697                        app.adjType = "pausing";
19698                    }
19699                    if (procState > PROCESS_STATE_CUR_TOP) {
19700                        procState = PROCESS_STATE_CUR_TOP;
19701                    }
19702                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19703                    app.cached = false;
19704                    app.empty = false;
19705                    foregroundActivities = true;
19706                } else if (r.state == ActivityState.STOPPING) {
19707                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19708                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19709                        app.adjType = "stopping";
19710                    }
19711                    // For the process state, we will at this point consider the
19712                    // process to be cached.  It will be cached either as an activity
19713                    // or empty depending on whether the activity is finishing.  We do
19714                    // this so that we can treat the process as cached for purposes of
19715                    // memory trimming (determing current memory level, trim command to
19716                    // send to process) since there can be an arbitrary number of stopping
19717                    // processes and they should soon all go into the cached state.
19718                    if (!r.finishing) {
19719                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19720                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19721                        }
19722                    }
19723                    app.cached = false;
19724                    app.empty = false;
19725                    foregroundActivities = true;
19726                } else {
19727                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19728                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19729                        app.adjType = "cch-act";
19730                    }
19731                }
19732            }
19733            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19734                adj += minLayer;
19735            }
19736        }
19737
19738        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19739                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19740            if (app.foregroundServices) {
19741                // The user is aware of this app, so make it visible.
19742                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19743                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19744                app.cached = false;
19745                app.adjType = "fg-service";
19746                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19747            } else if (app.forcingToForeground != null) {
19748                // The user is aware of this app, so make it visible.
19749                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19750                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19751                app.cached = false;
19752                app.adjType = "force-fg";
19753                app.adjSource = app.forcingToForeground;
19754                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19755            }
19756        }
19757
19758        if (app == mHeavyWeightProcess) {
19759            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19760                // We don't want to kill the current heavy-weight process.
19761                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19762                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19763                app.cached = false;
19764                app.adjType = "heavy";
19765            }
19766            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19767                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19768            }
19769        }
19770
19771        if (app == mHomeProcess) {
19772            if (adj > ProcessList.HOME_APP_ADJ) {
19773                // This process is hosting what we currently consider to be the
19774                // home app, so we don't want to let it go into the background.
19775                adj = ProcessList.HOME_APP_ADJ;
19776                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19777                app.cached = false;
19778                app.adjType = "home";
19779            }
19780            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19781                procState = ActivityManager.PROCESS_STATE_HOME;
19782            }
19783        }
19784
19785        if (app == mPreviousProcess && app.activities.size() > 0) {
19786            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19787                // This was the previous process that showed UI to the user.
19788                // We want to try to keep it around more aggressively, to give
19789                // a good experience around switching between two apps.
19790                adj = ProcessList.PREVIOUS_APP_ADJ;
19791                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19792                app.cached = false;
19793                app.adjType = "previous";
19794            }
19795            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19796                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19797            }
19798        }
19799
19800        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19801                + " reason=" + app.adjType);
19802
19803        // By default, we use the computed adjustment.  It may be changed if
19804        // there are applications dependent on our services or providers, but
19805        // this gives us a baseline and makes sure we don't get into an
19806        // infinite recursion.
19807        app.adjSeq = mAdjSeq;
19808        app.curRawAdj = adj;
19809        app.hasStartedServices = false;
19810
19811        if (mBackupTarget != null && app == mBackupTarget.app) {
19812            // If possible we want to avoid killing apps while they're being backed up
19813            if (adj > ProcessList.BACKUP_APP_ADJ) {
19814                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19815                adj = ProcessList.BACKUP_APP_ADJ;
19816                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19817                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19818                }
19819                app.adjType = "backup";
19820                app.cached = false;
19821            }
19822            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19823                procState = ActivityManager.PROCESS_STATE_BACKUP;
19824            }
19825        }
19826
19827        boolean mayBeTop = false;
19828
19829        for (int is = app.services.size()-1;
19830                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19831                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19832                        || procState > ActivityManager.PROCESS_STATE_TOP);
19833                is--) {
19834            ServiceRecord s = app.services.valueAt(is);
19835            if (s.startRequested) {
19836                app.hasStartedServices = true;
19837                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19838                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19839                }
19840                if (app.hasShownUi && app != mHomeProcess) {
19841                    // If this process has shown some UI, let it immediately
19842                    // go to the LRU list because it may be pretty heavy with
19843                    // UI stuff.  We'll tag it with a label just to help
19844                    // debug and understand what is going on.
19845                    if (adj > ProcessList.SERVICE_ADJ) {
19846                        app.adjType = "cch-started-ui-services";
19847                    }
19848                } else {
19849                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19850                        // This service has seen some activity within
19851                        // recent memory, so we will keep its process ahead
19852                        // of the background processes.
19853                        if (adj > ProcessList.SERVICE_ADJ) {
19854                            adj = ProcessList.SERVICE_ADJ;
19855                            app.adjType = "started-services";
19856                            app.cached = false;
19857                        }
19858                    }
19859                    // If we have let the service slide into the background
19860                    // state, still have some text describing what it is doing
19861                    // even though the service no longer has an impact.
19862                    if (adj > ProcessList.SERVICE_ADJ) {
19863                        app.adjType = "cch-started-services";
19864                    }
19865                }
19866            }
19867
19868            for (int conni = s.connections.size()-1;
19869                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19870                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19871                            || procState > ActivityManager.PROCESS_STATE_TOP);
19872                    conni--) {
19873                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19874                for (int i = 0;
19875                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19876                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19877                                || procState > ActivityManager.PROCESS_STATE_TOP);
19878                        i++) {
19879                    // XXX should compute this based on the max of
19880                    // all connected clients.
19881                    ConnectionRecord cr = clist.get(i);
19882                    if (cr.binding.client == app) {
19883                        // Binding to ourself is not interesting.
19884                        continue;
19885                    }
19886
19887                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19888                        ProcessRecord client = cr.binding.client;
19889                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19890                                TOP_APP, doingAll, now);
19891                        int clientProcState = client.curProcState;
19892                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19893                            // If the other app is cached for any reason, for purposes here
19894                            // we are going to consider it empty.  The specific cached state
19895                            // doesn't propagate except under certain conditions.
19896                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19897                        }
19898                        String adjType = null;
19899                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19900                            // Not doing bind OOM management, so treat
19901                            // this guy more like a started service.
19902                            if (app.hasShownUi && app != mHomeProcess) {
19903                                // If this process has shown some UI, let it immediately
19904                                // go to the LRU list because it may be pretty heavy with
19905                                // UI stuff.  We'll tag it with a label just to help
19906                                // debug and understand what is going on.
19907                                if (adj > clientAdj) {
19908                                    adjType = "cch-bound-ui-services";
19909                                }
19910                                app.cached = false;
19911                                clientAdj = adj;
19912                                clientProcState = procState;
19913                            } else {
19914                                if (now >= (s.lastActivity
19915                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19916                                    // This service has not seen activity within
19917                                    // recent memory, so allow it to drop to the
19918                                    // LRU list if there is no other reason to keep
19919                                    // it around.  We'll also tag it with a label just
19920                                    // to help debug and undertand what is going on.
19921                                    if (adj > clientAdj) {
19922                                        adjType = "cch-bound-services";
19923                                    }
19924                                    clientAdj = adj;
19925                                }
19926                            }
19927                        }
19928                        if (adj > clientAdj) {
19929                            // If this process has recently shown UI, and
19930                            // the process that is binding to it is less
19931                            // important than being visible, then we don't
19932                            // care about the binding as much as we care
19933                            // about letting this process get into the LRU
19934                            // list to be killed and restarted if needed for
19935                            // memory.
19936                            if (app.hasShownUi && app != mHomeProcess
19937                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19938                                adjType = "cch-bound-ui-services";
19939                            } else {
19940                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19941                                        |Context.BIND_IMPORTANT)) != 0) {
19942                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19943                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19944                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19945                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19946                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19947                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19948                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19949                                    adj = clientAdj;
19950                                } else {
19951                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19952                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19953                                    }
19954                                }
19955                                if (!client.cached) {
19956                                    app.cached = false;
19957                                }
19958                                adjType = "service";
19959                            }
19960                        }
19961                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19962                            // This will treat important bound services identically to
19963                            // the top app, which may behave differently than generic
19964                            // foreground work.
19965                            if (client.curSchedGroup > schedGroup) {
19966                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19967                                    schedGroup = client.curSchedGroup;
19968                                } else {
19969                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19970                                }
19971                            }
19972                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19973                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19974                                    // Special handling of clients who are in the top state.
19975                                    // We *may* want to consider this process to be in the
19976                                    // top state as well, but only if there is not another
19977                                    // reason for it to be running.  Being on the top is a
19978                                    // special state, meaning you are specifically running
19979                                    // for the current top app.  If the process is already
19980                                    // running in the background for some other reason, it
19981                                    // is more important to continue considering it to be
19982                                    // in the background state.
19983                                    mayBeTop = true;
19984                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19985                                } else {
19986                                    // Special handling for above-top states (persistent
19987                                    // processes).  These should not bring the current process
19988                                    // into the top state, since they are not on top.  Instead
19989                                    // give them the best state after that.
19990                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19991                                        clientProcState =
19992                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19993                                    } else if (mWakefulness
19994                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19995                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19996                                                    != 0) {
19997                                        clientProcState =
19998                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19999                                    } else {
20000                                        clientProcState =
20001                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20002                                    }
20003                                }
20004                            }
20005                        } else {
20006                            if (clientProcState <
20007                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20008                                clientProcState =
20009                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20010                            }
20011                        }
20012                        if (procState > clientProcState) {
20013                            procState = clientProcState;
20014                        }
20015                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20016                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20017                            app.pendingUiClean = true;
20018                        }
20019                        if (adjType != null) {
20020                            app.adjType = adjType;
20021                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20022                                    .REASON_SERVICE_IN_USE;
20023                            app.adjSource = cr.binding.client;
20024                            app.adjSourceProcState = clientProcState;
20025                            app.adjTarget = s.name;
20026                        }
20027                    }
20028                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20029                        app.treatLikeActivity = true;
20030                    }
20031                    final ActivityRecord a = cr.activity;
20032                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20033                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20034                            (a.visible || a.state == ActivityState.RESUMED ||
20035                             a.state == ActivityState.PAUSING)) {
20036                            adj = ProcessList.FOREGROUND_APP_ADJ;
20037                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20038                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20039                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20040                                } else {
20041                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20042                                }
20043                            }
20044                            app.cached = false;
20045                            app.adjType = "service";
20046                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20047                                    .REASON_SERVICE_IN_USE;
20048                            app.adjSource = a;
20049                            app.adjSourceProcState = procState;
20050                            app.adjTarget = s.name;
20051                        }
20052                    }
20053                }
20054            }
20055        }
20056
20057        for (int provi = app.pubProviders.size()-1;
20058                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20059                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20060                        || procState > ActivityManager.PROCESS_STATE_TOP);
20061                provi--) {
20062            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20063            for (int i = cpr.connections.size()-1;
20064                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20065                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20066                            || procState > ActivityManager.PROCESS_STATE_TOP);
20067                    i--) {
20068                ContentProviderConnection conn = cpr.connections.get(i);
20069                ProcessRecord client = conn.client;
20070                if (client == app) {
20071                    // Being our own client is not interesting.
20072                    continue;
20073                }
20074                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20075                int clientProcState = client.curProcState;
20076                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20077                    // If the other app is cached for any reason, for purposes here
20078                    // we are going to consider it empty.
20079                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20080                }
20081                if (adj > clientAdj) {
20082                    if (app.hasShownUi && app != mHomeProcess
20083                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20084                        app.adjType = "cch-ui-provider";
20085                    } else {
20086                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20087                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20088                        app.adjType = "provider";
20089                    }
20090                    app.cached &= client.cached;
20091                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20092                            .REASON_PROVIDER_IN_USE;
20093                    app.adjSource = client;
20094                    app.adjSourceProcState = clientProcState;
20095                    app.adjTarget = cpr.name;
20096                }
20097                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20098                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20099                        // Special handling of clients who are in the top state.
20100                        // We *may* want to consider this process to be in the
20101                        // top state as well, but only if there is not another
20102                        // reason for it to be running.  Being on the top is a
20103                        // special state, meaning you are specifically running
20104                        // for the current top app.  If the process is already
20105                        // running in the background for some other reason, it
20106                        // is more important to continue considering it to be
20107                        // in the background state.
20108                        mayBeTop = true;
20109                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20110                    } else {
20111                        // Special handling for above-top states (persistent
20112                        // processes).  These should not bring the current process
20113                        // into the top state, since they are not on top.  Instead
20114                        // give them the best state after that.
20115                        clientProcState =
20116                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20117                    }
20118                }
20119                if (procState > clientProcState) {
20120                    procState = clientProcState;
20121                }
20122                if (client.curSchedGroup > schedGroup) {
20123                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20124                }
20125            }
20126            // If the provider has external (non-framework) process
20127            // dependencies, ensure that its adjustment is at least
20128            // FOREGROUND_APP_ADJ.
20129            if (cpr.hasExternalProcessHandles()) {
20130                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20131                    adj = ProcessList.FOREGROUND_APP_ADJ;
20132                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20133                    app.cached = false;
20134                    app.adjType = "provider";
20135                    app.adjTarget = cpr.name;
20136                }
20137                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20138                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20139                }
20140            }
20141        }
20142
20143        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20144            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20145                adj = ProcessList.PREVIOUS_APP_ADJ;
20146                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20147                app.cached = false;
20148                app.adjType = "provider";
20149            }
20150            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20151                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20152            }
20153        }
20154
20155        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20156            // A client of one of our services or providers is in the top state.  We
20157            // *may* want to be in the top state, but not if we are already running in
20158            // the background for some other reason.  For the decision here, we are going
20159            // to pick out a few specific states that we want to remain in when a client
20160            // is top (states that tend to be longer-term) and otherwise allow it to go
20161            // to the top state.
20162            switch (procState) {
20163                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20164                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20165                case ActivityManager.PROCESS_STATE_SERVICE:
20166                    // These all are longer-term states, so pull them up to the top
20167                    // of the background states, but not all the way to the top state.
20168                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20169                    break;
20170                default:
20171                    // Otherwise, top is a better choice, so take it.
20172                    procState = ActivityManager.PROCESS_STATE_TOP;
20173                    break;
20174            }
20175        }
20176
20177        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20178            if (app.hasClientActivities) {
20179                // This is a cached process, but with client activities.  Mark it so.
20180                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20181                app.adjType = "cch-client-act";
20182            } else if (app.treatLikeActivity) {
20183                // This is a cached process, but somebody wants us to treat it like it has
20184                // an activity, okay!
20185                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20186                app.adjType = "cch-as-act";
20187            }
20188        }
20189
20190        if (adj == ProcessList.SERVICE_ADJ) {
20191            if (doingAll) {
20192                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20193                mNewNumServiceProcs++;
20194                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20195                if (!app.serviceb) {
20196                    // This service isn't far enough down on the LRU list to
20197                    // normally be a B service, but if we are low on RAM and it
20198                    // is large we want to force it down since we would prefer to
20199                    // keep launcher over it.
20200                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20201                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20202                        app.serviceHighRam = true;
20203                        app.serviceb = true;
20204                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20205                    } else {
20206                        mNewNumAServiceProcs++;
20207                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20208                    }
20209                } else {
20210                    app.serviceHighRam = false;
20211                }
20212            }
20213            if (app.serviceb) {
20214                adj = ProcessList.SERVICE_B_ADJ;
20215            }
20216        }
20217
20218        app.curRawAdj = adj;
20219
20220        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20221        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20222        if (adj > app.maxAdj) {
20223            adj = app.maxAdj;
20224            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20225                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20226            }
20227        }
20228
20229        // Do final modification to adj.  Everything we do between here and applying
20230        // the final setAdj must be done in this function, because we will also use
20231        // it when computing the final cached adj later.  Note that we don't need to
20232        // worry about this for max adj above, since max adj will always be used to
20233        // keep it out of the cached vaues.
20234        app.curAdj = app.modifyRawOomAdj(adj);
20235        app.curSchedGroup = schedGroup;
20236        app.curProcState = procState;
20237        app.foregroundActivities = foregroundActivities;
20238
20239        return app.curRawAdj;
20240    }
20241
20242    /**
20243     * Record new PSS sample for a process.
20244     */
20245    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20246            long now) {
20247        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20248                swapPss * 1024);
20249        proc.lastPssTime = now;
20250        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20251        if (DEBUG_PSS) Slog.d(TAG_PSS,
20252                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20253                + " state=" + ProcessList.makeProcStateString(procState));
20254        if (proc.initialIdlePss == 0) {
20255            proc.initialIdlePss = pss;
20256        }
20257        proc.lastPss = pss;
20258        proc.lastSwapPss = swapPss;
20259        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20260            proc.lastCachedPss = pss;
20261            proc.lastCachedSwapPss = swapPss;
20262        }
20263
20264        final SparseArray<Pair<Long, String>> watchUids
20265                = mMemWatchProcesses.getMap().get(proc.processName);
20266        Long check = null;
20267        if (watchUids != null) {
20268            Pair<Long, String> val = watchUids.get(proc.uid);
20269            if (val == null) {
20270                val = watchUids.get(0);
20271            }
20272            if (val != null) {
20273                check = val.first;
20274            }
20275        }
20276        if (check != null) {
20277            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20278                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20279                if (!isDebuggable) {
20280                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20281                        isDebuggable = true;
20282                    }
20283                }
20284                if (isDebuggable) {
20285                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20286                    final ProcessRecord myProc = proc;
20287                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20288                    mMemWatchDumpProcName = proc.processName;
20289                    mMemWatchDumpFile = heapdumpFile.toString();
20290                    mMemWatchDumpPid = proc.pid;
20291                    mMemWatchDumpUid = proc.uid;
20292                    BackgroundThread.getHandler().post(new Runnable() {
20293                        @Override
20294                        public void run() {
20295                            revokeUriPermission(ActivityThread.currentActivityThread()
20296                                            .getApplicationThread(),
20297                                    DumpHeapActivity.JAVA_URI,
20298                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20299                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20300                                    UserHandle.myUserId());
20301                            ParcelFileDescriptor fd = null;
20302                            try {
20303                                heapdumpFile.delete();
20304                                fd = ParcelFileDescriptor.open(heapdumpFile,
20305                                        ParcelFileDescriptor.MODE_CREATE |
20306                                                ParcelFileDescriptor.MODE_TRUNCATE |
20307                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20308                                                ParcelFileDescriptor.MODE_APPEND);
20309                                IApplicationThread thread = myProc.thread;
20310                                if (thread != null) {
20311                                    try {
20312                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20313                                                "Requesting dump heap from "
20314                                                + myProc + " to " + heapdumpFile);
20315                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20316                                    } catch (RemoteException e) {
20317                                    }
20318                                }
20319                            } catch (FileNotFoundException e) {
20320                                e.printStackTrace();
20321                            } finally {
20322                                if (fd != null) {
20323                                    try {
20324                                        fd.close();
20325                                    } catch (IOException e) {
20326                                    }
20327                                }
20328                            }
20329                        }
20330                    });
20331                } else {
20332                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20333                            + ", but debugging not enabled");
20334                }
20335            }
20336        }
20337    }
20338
20339    /**
20340     * Schedule PSS collection of a process.
20341     */
20342    void requestPssLocked(ProcessRecord proc, int procState) {
20343        if (mPendingPssProcesses.contains(proc)) {
20344            return;
20345        }
20346        if (mPendingPssProcesses.size() == 0) {
20347            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20348        }
20349        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20350        proc.pssProcState = procState;
20351        mPendingPssProcesses.add(proc);
20352    }
20353
20354    /**
20355     * Schedule PSS collection of all processes.
20356     */
20357    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20358        if (!always) {
20359            if (now < (mLastFullPssTime +
20360                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20361                return;
20362            }
20363        }
20364        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20365        mLastFullPssTime = now;
20366        mFullPssPending = true;
20367        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20368        mPendingPssProcesses.clear();
20369        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20370            ProcessRecord app = mLruProcesses.get(i);
20371            if (app.thread == null
20372                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20373                continue;
20374            }
20375            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20376                app.pssProcState = app.setProcState;
20377                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20378                        mTestPssMode, isSleepingLocked(), now);
20379                mPendingPssProcesses.add(app);
20380            }
20381        }
20382        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20383    }
20384
20385    public void setTestPssMode(boolean enabled) {
20386        synchronized (this) {
20387            mTestPssMode = enabled;
20388            if (enabled) {
20389                // Whenever we enable the mode, we want to take a snapshot all of current
20390                // process mem use.
20391                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20392            }
20393        }
20394    }
20395
20396    /**
20397     * Ask a given process to GC right now.
20398     */
20399    final void performAppGcLocked(ProcessRecord app) {
20400        try {
20401            app.lastRequestedGc = SystemClock.uptimeMillis();
20402            if (app.thread != null) {
20403                if (app.reportLowMemory) {
20404                    app.reportLowMemory = false;
20405                    app.thread.scheduleLowMemory();
20406                } else {
20407                    app.thread.processInBackground();
20408                }
20409            }
20410        } catch (Exception e) {
20411            // whatever.
20412        }
20413    }
20414
20415    /**
20416     * Returns true if things are idle enough to perform GCs.
20417     */
20418    private final boolean canGcNowLocked() {
20419        boolean processingBroadcasts = false;
20420        for (BroadcastQueue q : mBroadcastQueues) {
20421            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20422                processingBroadcasts = true;
20423            }
20424        }
20425        return !processingBroadcasts
20426                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20427    }
20428
20429    /**
20430     * Perform GCs on all processes that are waiting for it, but only
20431     * if things are idle.
20432     */
20433    final void performAppGcsLocked() {
20434        final int N = mProcessesToGc.size();
20435        if (N <= 0) {
20436            return;
20437        }
20438        if (canGcNowLocked()) {
20439            while (mProcessesToGc.size() > 0) {
20440                ProcessRecord proc = mProcessesToGc.remove(0);
20441                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20442                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20443                            <= SystemClock.uptimeMillis()) {
20444                        // To avoid spamming the system, we will GC processes one
20445                        // at a time, waiting a few seconds between each.
20446                        performAppGcLocked(proc);
20447                        scheduleAppGcsLocked();
20448                        return;
20449                    } else {
20450                        // It hasn't been long enough since we last GCed this
20451                        // process...  put it in the list to wait for its time.
20452                        addProcessToGcListLocked(proc);
20453                        break;
20454                    }
20455                }
20456            }
20457
20458            scheduleAppGcsLocked();
20459        }
20460    }
20461
20462    /**
20463     * If all looks good, perform GCs on all processes waiting for them.
20464     */
20465    final void performAppGcsIfAppropriateLocked() {
20466        if (canGcNowLocked()) {
20467            performAppGcsLocked();
20468            return;
20469        }
20470        // Still not idle, wait some more.
20471        scheduleAppGcsLocked();
20472    }
20473
20474    /**
20475     * Schedule the execution of all pending app GCs.
20476     */
20477    final void scheduleAppGcsLocked() {
20478        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20479
20480        if (mProcessesToGc.size() > 0) {
20481            // Schedule a GC for the time to the next process.
20482            ProcessRecord proc = mProcessesToGc.get(0);
20483            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20484
20485            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20486            long now = SystemClock.uptimeMillis();
20487            if (when < (now+GC_TIMEOUT)) {
20488                when = now + GC_TIMEOUT;
20489            }
20490            mHandler.sendMessageAtTime(msg, when);
20491        }
20492    }
20493
20494    /**
20495     * Add a process to the array of processes waiting to be GCed.  Keeps the
20496     * list in sorted order by the last GC time.  The process can't already be
20497     * on the list.
20498     */
20499    final void addProcessToGcListLocked(ProcessRecord proc) {
20500        boolean added = false;
20501        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20502            if (mProcessesToGc.get(i).lastRequestedGc <
20503                    proc.lastRequestedGc) {
20504                added = true;
20505                mProcessesToGc.add(i+1, proc);
20506                break;
20507            }
20508        }
20509        if (!added) {
20510            mProcessesToGc.add(0, proc);
20511        }
20512    }
20513
20514    /**
20515     * Set up to ask a process to GC itself.  This will either do it
20516     * immediately, or put it on the list of processes to gc the next
20517     * time things are idle.
20518     */
20519    final void scheduleAppGcLocked(ProcessRecord app) {
20520        long now = SystemClock.uptimeMillis();
20521        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20522            return;
20523        }
20524        if (!mProcessesToGc.contains(app)) {
20525            addProcessToGcListLocked(app);
20526            scheduleAppGcsLocked();
20527        }
20528    }
20529
20530    final void checkExcessivePowerUsageLocked(boolean doKills) {
20531        updateCpuStatsNow();
20532
20533        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20534        boolean doWakeKills = doKills;
20535        boolean doCpuKills = doKills;
20536        if (mLastPowerCheckRealtime == 0) {
20537            doWakeKills = false;
20538        }
20539        if (mLastPowerCheckUptime == 0) {
20540            doCpuKills = false;
20541        }
20542        if (stats.isScreenOn()) {
20543            doWakeKills = false;
20544        }
20545        final long curRealtime = SystemClock.elapsedRealtime();
20546        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20547        final long curUptime = SystemClock.uptimeMillis();
20548        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20549        mLastPowerCheckRealtime = curRealtime;
20550        mLastPowerCheckUptime = curUptime;
20551        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20552            doWakeKills = false;
20553        }
20554        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20555            doCpuKills = false;
20556        }
20557        int i = mLruProcesses.size();
20558        while (i > 0) {
20559            i--;
20560            ProcessRecord app = mLruProcesses.get(i);
20561            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20562                long wtime;
20563                synchronized (stats) {
20564                    wtime = stats.getProcessWakeTime(app.info.uid,
20565                            app.pid, curRealtime);
20566                }
20567                long wtimeUsed = wtime - app.lastWakeTime;
20568                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20569                if (DEBUG_POWER) {
20570                    StringBuilder sb = new StringBuilder(128);
20571                    sb.append("Wake for ");
20572                    app.toShortString(sb);
20573                    sb.append(": over ");
20574                    TimeUtils.formatDuration(realtimeSince, sb);
20575                    sb.append(" used ");
20576                    TimeUtils.formatDuration(wtimeUsed, sb);
20577                    sb.append(" (");
20578                    sb.append((wtimeUsed*100)/realtimeSince);
20579                    sb.append("%)");
20580                    Slog.i(TAG_POWER, sb.toString());
20581                    sb.setLength(0);
20582                    sb.append("CPU for ");
20583                    app.toShortString(sb);
20584                    sb.append(": over ");
20585                    TimeUtils.formatDuration(uptimeSince, sb);
20586                    sb.append(" used ");
20587                    TimeUtils.formatDuration(cputimeUsed, sb);
20588                    sb.append(" (");
20589                    sb.append((cputimeUsed*100)/uptimeSince);
20590                    sb.append("%)");
20591                    Slog.i(TAG_POWER, sb.toString());
20592                }
20593                // If a process has held a wake lock for more
20594                // than 50% of the time during this period,
20595                // that sounds bad.  Kill!
20596                if (doWakeKills && realtimeSince > 0
20597                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20598                    synchronized (stats) {
20599                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20600                                realtimeSince, wtimeUsed);
20601                    }
20602                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20603                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20604                } else if (doCpuKills && uptimeSince > 0
20605                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20606                    synchronized (stats) {
20607                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20608                                uptimeSince, cputimeUsed);
20609                    }
20610                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20611                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20612                } else {
20613                    app.lastWakeTime = wtime;
20614                    app.lastCpuTime = app.curCpuTime;
20615                }
20616            }
20617        }
20618    }
20619
20620    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20621            long nowElapsed) {
20622        boolean success = true;
20623
20624        if (app.curRawAdj != app.setRawAdj) {
20625            app.setRawAdj = app.curRawAdj;
20626        }
20627
20628        int changes = 0;
20629
20630        if (app.curAdj != app.setAdj) {
20631            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20632            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20633                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20634                    + app.adjType);
20635            app.setAdj = app.curAdj;
20636            app.verifiedAdj = ProcessList.INVALID_ADJ;
20637        }
20638
20639        if (app.setSchedGroup != app.curSchedGroup) {
20640            int oldSchedGroup = app.setSchedGroup;
20641            app.setSchedGroup = app.curSchedGroup;
20642            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20643                    "Setting sched group of " + app.processName
20644                    + " to " + app.curSchedGroup);
20645            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20646                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20647                app.kill(app.waitingToKill, true);
20648                success = false;
20649            } else {
20650                int processGroup;
20651                switch (app.curSchedGroup) {
20652                    case ProcessList.SCHED_GROUP_BACKGROUND:
20653                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20654                        break;
20655                    case ProcessList.SCHED_GROUP_TOP_APP:
20656                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20657                        processGroup = Process.THREAD_GROUP_TOP_APP;
20658                        break;
20659                    default:
20660                        processGroup = Process.THREAD_GROUP_DEFAULT;
20661                        break;
20662                }
20663                long oldId = Binder.clearCallingIdentity();
20664                try {
20665                    Process.setProcessGroup(app.pid, processGroup);
20666                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20667                        // do nothing if we already switched to RT
20668                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20669                            // Switch VR thread for app to SCHED_FIFO
20670                            if (mInVrMode && app.vrThreadTid != 0) {
20671                                try {
20672                                    Process.setThreadScheduler(app.vrThreadTid,
20673                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20674                                } catch (IllegalArgumentException e) {
20675                                    // thread died, ignore
20676                                }
20677                            }
20678                            if (mUseFifoUiScheduling) {
20679                                // Switch UI pipeline for app to SCHED_FIFO
20680                                app.savedPriority = Process.getThreadPriority(app.pid);
20681                                try {
20682                                    Process.setThreadScheduler(app.pid,
20683                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20684                                } catch (IllegalArgumentException e) {
20685                                    // thread died, ignore
20686                                }
20687                                if (app.renderThreadTid != 0) {
20688                                    try {
20689                                        Process.setThreadScheduler(app.renderThreadTid,
20690                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20691                                    } catch (IllegalArgumentException e) {
20692                                        // thread died, ignore
20693                                    }
20694                                    if (DEBUG_OOM_ADJ) {
20695                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20696                                            app.renderThreadTid + ") to FIFO");
20697                                    }
20698                                } else {
20699                                    if (DEBUG_OOM_ADJ) {
20700                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20701                                    }
20702                                }
20703                            } else {
20704                                // Boost priority for top app UI and render threads
20705                                Process.setThreadPriority(app.pid, -10);
20706                                if (app.renderThreadTid != 0) {
20707                                    try {
20708                                        Process.setThreadPriority(app.renderThreadTid, -10);
20709                                    } catch (IllegalArgumentException e) {
20710                                        // thread died, ignore
20711                                    }
20712                                }
20713                            }
20714                        }
20715                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20716                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20717                        // Reset VR thread to SCHED_OTHER
20718                        // Safe to do even if we're not in VR mode
20719                        if (app.vrThreadTid != 0) {
20720                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20721                        }
20722                        if (mUseFifoUiScheduling) {
20723                            // Reset UI pipeline to SCHED_OTHER
20724                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20725                            Process.setThreadPriority(app.pid, app.savedPriority);
20726                            if (app.renderThreadTid != 0) {
20727                                Process.setThreadScheduler(app.renderThreadTid,
20728                                    Process.SCHED_OTHER, 0);
20729                                Process.setThreadPriority(app.renderThreadTid, -4);
20730                            }
20731                        } else {
20732                            // Reset priority for top app UI and render threads
20733                            Process.setThreadPriority(app.pid, 0);
20734                            if (app.renderThreadTid != 0) {
20735                                Process.setThreadPriority(app.renderThreadTid, 0);
20736                            }
20737                        }
20738                    }
20739                } catch (Exception e) {
20740                    Slog.w(TAG, "Failed setting process group of " + app.pid
20741                            + " to " + app.curSchedGroup);
20742                    e.printStackTrace();
20743                } finally {
20744                    Binder.restoreCallingIdentity(oldId);
20745                }
20746            }
20747        }
20748        if (app.repForegroundActivities != app.foregroundActivities) {
20749            app.repForegroundActivities = app.foregroundActivities;
20750            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20751        }
20752        if (app.repProcState != app.curProcState) {
20753            app.repProcState = app.curProcState;
20754            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20755            if (app.thread != null) {
20756                try {
20757                    if (false) {
20758                        //RuntimeException h = new RuntimeException("here");
20759                        Slog.i(TAG, "Sending new process state " + app.repProcState
20760                                + " to " + app /*, h*/);
20761                    }
20762                    app.thread.setProcessState(app.repProcState);
20763                } catch (RemoteException e) {
20764                }
20765            }
20766        }
20767        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20768                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20769            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20770                // Experimental code to more aggressively collect pss while
20771                // running test...  the problem is that this tends to collect
20772                // the data right when a process is transitioning between process
20773                // states, which well tend to give noisy data.
20774                long start = SystemClock.uptimeMillis();
20775                long pss = Debug.getPss(app.pid, mTmpLong, null);
20776                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20777                mPendingPssProcesses.remove(app);
20778                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20779                        + " to " + app.curProcState + ": "
20780                        + (SystemClock.uptimeMillis()-start) + "ms");
20781            }
20782            app.lastStateTime = now;
20783            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20784                    mTestPssMode, isSleepingLocked(), now);
20785            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20786                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20787                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20788                    + (app.nextPssTime-now) + ": " + app);
20789        } else {
20790            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20791                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20792                    mTestPssMode)))) {
20793                requestPssLocked(app, app.setProcState);
20794                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20795                        mTestPssMode, isSleepingLocked(), now);
20796            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20797                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20798        }
20799        if (app.setProcState != app.curProcState) {
20800            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20801                    "Proc state change of " + app.processName
20802                            + " to " + app.curProcState);
20803            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20804            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20805            if (setImportant && !curImportant) {
20806                // This app is no longer something we consider important enough to allow to
20807                // use arbitrary amounts of battery power.  Note
20808                // its current wake lock time to later know to kill it if
20809                // it is not behaving well.
20810                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20811                synchronized (stats) {
20812                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20813                            app.pid, nowElapsed);
20814                }
20815                app.lastCpuTime = app.curCpuTime;
20816
20817            }
20818            // Inform UsageStats of important process state change
20819            // Must be called before updating setProcState
20820            maybeUpdateUsageStatsLocked(app, nowElapsed);
20821
20822            app.setProcState = app.curProcState;
20823            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20824                app.notCachedSinceIdle = false;
20825            }
20826            if (!doingAll) {
20827                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20828            } else {
20829                app.procStateChanged = true;
20830            }
20831        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20832                > USAGE_STATS_INTERACTION_INTERVAL) {
20833            // For apps that sit around for a long time in the interactive state, we need
20834            // to report this at least once a day so they don't go idle.
20835            maybeUpdateUsageStatsLocked(app, nowElapsed);
20836        }
20837
20838        if (changes != 0) {
20839            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20840                    "Changes in " + app + ": " + changes);
20841            int i = mPendingProcessChanges.size()-1;
20842            ProcessChangeItem item = null;
20843            while (i >= 0) {
20844                item = mPendingProcessChanges.get(i);
20845                if (item.pid == app.pid) {
20846                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20847                            "Re-using existing item: " + item);
20848                    break;
20849                }
20850                i--;
20851            }
20852            if (i < 0) {
20853                // No existing item in pending changes; need a new one.
20854                final int NA = mAvailProcessChanges.size();
20855                if (NA > 0) {
20856                    item = mAvailProcessChanges.remove(NA-1);
20857                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20858                            "Retrieving available item: " + item);
20859                } else {
20860                    item = new ProcessChangeItem();
20861                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20862                            "Allocating new item: " + item);
20863                }
20864                item.changes = 0;
20865                item.pid = app.pid;
20866                item.uid = app.info.uid;
20867                if (mPendingProcessChanges.size() == 0) {
20868                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20869                            "*** Enqueueing dispatch processes changed!");
20870                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20871                }
20872                mPendingProcessChanges.add(item);
20873            }
20874            item.changes |= changes;
20875            item.processState = app.repProcState;
20876            item.foregroundActivities = app.repForegroundActivities;
20877            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20878                    "Item " + Integer.toHexString(System.identityHashCode(item))
20879                    + " " + app.toShortString() + ": changes=" + item.changes
20880                    + " procState=" + item.processState
20881                    + " foreground=" + item.foregroundActivities
20882                    + " type=" + app.adjType + " source=" + app.adjSource
20883                    + " target=" + app.adjTarget);
20884        }
20885
20886        return success;
20887    }
20888
20889    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20890        final UidRecord.ChangeItem pendingChange;
20891        if (uidRec == null || uidRec.pendingChange == null) {
20892            if (mPendingUidChanges.size() == 0) {
20893                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20894                        "*** Enqueueing dispatch uid changed!");
20895                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20896            }
20897            final int NA = mAvailUidChanges.size();
20898            if (NA > 0) {
20899                pendingChange = mAvailUidChanges.remove(NA-1);
20900                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20901                        "Retrieving available item: " + pendingChange);
20902            } else {
20903                pendingChange = new UidRecord.ChangeItem();
20904                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20905                        "Allocating new item: " + pendingChange);
20906            }
20907            if (uidRec != null) {
20908                uidRec.pendingChange = pendingChange;
20909                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20910                    // If this uid is going away, and we haven't yet reported it is gone,
20911                    // then do so now.
20912                    change = UidRecord.CHANGE_GONE_IDLE;
20913                }
20914            } else if (uid < 0) {
20915                throw new IllegalArgumentException("No UidRecord or uid");
20916            }
20917            pendingChange.uidRecord = uidRec;
20918            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20919            mPendingUidChanges.add(pendingChange);
20920        } else {
20921            pendingChange = uidRec.pendingChange;
20922            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20923                change = UidRecord.CHANGE_GONE_IDLE;
20924            }
20925        }
20926        pendingChange.change = change;
20927        pendingChange.processState = uidRec != null
20928                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20929        pendingChange.ephemeral = uidRec.ephemeral;
20930
20931        // Directly update the power manager, since we sit on top of it and it is critical
20932        // it be kept in sync (so wake locks will be held as soon as appropriate).
20933        if (mLocalPowerManager != null) {
20934            switch (change) {
20935                case UidRecord.CHANGE_GONE:
20936                case UidRecord.CHANGE_GONE_IDLE:
20937                    mLocalPowerManager.uidGone(pendingChange.uid);
20938                    break;
20939                case UidRecord.CHANGE_IDLE:
20940                    mLocalPowerManager.uidIdle(pendingChange.uid);
20941                    break;
20942                case UidRecord.CHANGE_ACTIVE:
20943                    mLocalPowerManager.uidActive(pendingChange.uid);
20944                    break;
20945                default:
20946                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
20947                            pendingChange.processState);
20948                    break;
20949            }
20950        }
20951    }
20952
20953    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20954            String authority) {
20955        if (app == null) return;
20956        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20957            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20958            if (userState == null) return;
20959            final long now = SystemClock.elapsedRealtime();
20960            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20961            if (lastReported == null || lastReported < now - 60 * 1000L) {
20962                if (mSystemReady) {
20963                    // Cannot touch the user stats if not system ready
20964                    mUsageStatsService.reportContentProviderUsage(
20965                            authority, providerPkgName, app.userId);
20966                }
20967                userState.mProviderLastReportedFg.put(authority, now);
20968            }
20969        }
20970    }
20971
20972    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20973        if (DEBUG_USAGE_STATS) {
20974            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20975                    + "] state changes: old = " + app.setProcState + ", new = "
20976                    + app.curProcState);
20977        }
20978        if (mUsageStatsService == null) {
20979            return;
20980        }
20981        boolean isInteraction;
20982        // To avoid some abuse patterns, we are going to be careful about what we consider
20983        // to be an app interaction.  Being the top activity doesn't count while the display
20984        // is sleeping, nor do short foreground services.
20985        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20986            isInteraction = true;
20987            app.fgInteractionTime = 0;
20988        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20989            if (app.fgInteractionTime == 0) {
20990                app.fgInteractionTime = nowElapsed;
20991                isInteraction = false;
20992            } else {
20993                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20994            }
20995        } else {
20996            // If the app was being forced to the foreground, by say a Toast, then
20997            // no need to treat it as an interaction
20998            isInteraction = app.forcingToForeground == null
20999                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21000            app.fgInteractionTime = 0;
21001        }
21002        if (isInteraction && (!app.reportedInteraction
21003                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21004            app.interactionEventTime = nowElapsed;
21005            String[] packages = app.getPackageList();
21006            if (packages != null) {
21007                for (int i = 0; i < packages.length; i++) {
21008                    mUsageStatsService.reportEvent(packages[i], app.userId,
21009                            UsageEvents.Event.SYSTEM_INTERACTION);
21010                }
21011            }
21012        }
21013        app.reportedInteraction = isInteraction;
21014        if (!isInteraction) {
21015            app.interactionEventTime = 0;
21016        }
21017    }
21018
21019    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21020        if (proc.thread != null) {
21021            if (proc.baseProcessTracker != null) {
21022                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21023            }
21024        }
21025    }
21026
21027    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21028            ProcessRecord TOP_APP, boolean doingAll, long now) {
21029        if (app.thread == null) {
21030            return false;
21031        }
21032
21033        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21034
21035        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21036    }
21037
21038    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21039            boolean oomAdj) {
21040        if (isForeground != proc.foregroundServices) {
21041            proc.foregroundServices = isForeground;
21042            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21043                    proc.info.uid);
21044            if (isForeground) {
21045                if (curProcs == null) {
21046                    curProcs = new ArrayList<ProcessRecord>();
21047                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21048                }
21049                if (!curProcs.contains(proc)) {
21050                    curProcs.add(proc);
21051                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21052                            proc.info.packageName, proc.info.uid);
21053                }
21054            } else {
21055                if (curProcs != null) {
21056                    if (curProcs.remove(proc)) {
21057                        mBatteryStatsService.noteEvent(
21058                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21059                                proc.info.packageName, proc.info.uid);
21060                        if (curProcs.size() <= 0) {
21061                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21062                        }
21063                    }
21064                }
21065            }
21066            if (oomAdj) {
21067                updateOomAdjLocked();
21068            }
21069        }
21070    }
21071
21072    private final ActivityRecord resumedAppLocked() {
21073        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21074        String pkg;
21075        int uid;
21076        if (act != null) {
21077            pkg = act.packageName;
21078            uid = act.info.applicationInfo.uid;
21079        } else {
21080            pkg = null;
21081            uid = -1;
21082        }
21083        // Has the UID or resumed package name changed?
21084        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21085                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21086            if (mCurResumedPackage != null) {
21087                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21088                        mCurResumedPackage, mCurResumedUid);
21089            }
21090            mCurResumedPackage = pkg;
21091            mCurResumedUid = uid;
21092            if (mCurResumedPackage != null) {
21093                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21094                        mCurResumedPackage, mCurResumedUid);
21095            }
21096        }
21097        return act;
21098    }
21099
21100    final boolean updateOomAdjLocked(ProcessRecord app) {
21101        final ActivityRecord TOP_ACT = resumedAppLocked();
21102        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21103        final boolean wasCached = app.cached;
21104
21105        mAdjSeq++;
21106
21107        // This is the desired cached adjusment we want to tell it to use.
21108        // If our app is currently cached, we know it, and that is it.  Otherwise,
21109        // we don't know it yet, and it needs to now be cached we will then
21110        // need to do a complete oom adj.
21111        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21112                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21113        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21114                SystemClock.uptimeMillis());
21115        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21116            // Changed to/from cached state, so apps after it in the LRU
21117            // list may also be changed.
21118            updateOomAdjLocked();
21119        }
21120        return success;
21121    }
21122
21123    final void updateOomAdjLocked() {
21124        final ActivityRecord TOP_ACT = resumedAppLocked();
21125        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21126        final long now = SystemClock.uptimeMillis();
21127        final long nowElapsed = SystemClock.elapsedRealtime();
21128        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21129        final int N = mLruProcesses.size();
21130
21131        if (false) {
21132            RuntimeException e = new RuntimeException();
21133            e.fillInStackTrace();
21134            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21135        }
21136
21137        // Reset state in all uid records.
21138        for (int i=mActiveUids.size()-1; i>=0; i--) {
21139            final UidRecord uidRec = mActiveUids.valueAt(i);
21140            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21141                    "Starting update of " + uidRec);
21142            uidRec.reset();
21143        }
21144
21145        mStackSupervisor.rankTaskLayersIfNeeded();
21146
21147        mAdjSeq++;
21148        mNewNumServiceProcs = 0;
21149        mNewNumAServiceProcs = 0;
21150
21151        final int emptyProcessLimit;
21152        final int cachedProcessLimit;
21153        if (mProcessLimit <= 0) {
21154            emptyProcessLimit = cachedProcessLimit = 0;
21155        } else if (mProcessLimit == 1) {
21156            emptyProcessLimit = 1;
21157            cachedProcessLimit = 0;
21158        } else {
21159            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
21160            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
21161        }
21162
21163        // Let's determine how many processes we have running vs.
21164        // how many slots we have for background processes; we may want
21165        // to put multiple processes in a slot of there are enough of
21166        // them.
21167        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21168                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21169        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21170        if (numEmptyProcs > cachedProcessLimit) {
21171            // If there are more empty processes than our limit on cached
21172            // processes, then use the cached process limit for the factor.
21173            // This ensures that the really old empty processes get pushed
21174            // down to the bottom, so if we are running low on memory we will
21175            // have a better chance at keeping around more cached processes
21176            // instead of a gazillion empty processes.
21177            numEmptyProcs = cachedProcessLimit;
21178        }
21179        int emptyFactor = numEmptyProcs/numSlots;
21180        if (emptyFactor < 1) emptyFactor = 1;
21181        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21182        if (cachedFactor < 1) cachedFactor = 1;
21183        int stepCached = 0;
21184        int stepEmpty = 0;
21185        int numCached = 0;
21186        int numEmpty = 0;
21187        int numTrimming = 0;
21188
21189        mNumNonCachedProcs = 0;
21190        mNumCachedHiddenProcs = 0;
21191
21192        // First update the OOM adjustment for each of the
21193        // application processes based on their current state.
21194        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21195        int nextCachedAdj = curCachedAdj+1;
21196        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21197        int nextEmptyAdj = curEmptyAdj+2;
21198        for (int i=N-1; i>=0; i--) {
21199            ProcessRecord app = mLruProcesses.get(i);
21200            if (!app.killedByAm && app.thread != null) {
21201                app.procStateChanged = false;
21202                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21203
21204                // If we haven't yet assigned the final cached adj
21205                // to the process, do that now.
21206                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21207                    switch (app.curProcState) {
21208                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21209                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21210                            // This process is a cached process holding activities...
21211                            // assign it the next cached value for that type, and then
21212                            // step that cached level.
21213                            app.curRawAdj = curCachedAdj;
21214                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21215                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21216                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21217                                    + ")");
21218                            if (curCachedAdj != nextCachedAdj) {
21219                                stepCached++;
21220                                if (stepCached >= cachedFactor) {
21221                                    stepCached = 0;
21222                                    curCachedAdj = nextCachedAdj;
21223                                    nextCachedAdj += 2;
21224                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21225                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21226                                    }
21227                                }
21228                            }
21229                            break;
21230                        default:
21231                            // For everything else, assign next empty cached process
21232                            // level and bump that up.  Note that this means that
21233                            // long-running services that have dropped down to the
21234                            // cached level will be treated as empty (since their process
21235                            // state is still as a service), which is what we want.
21236                            app.curRawAdj = curEmptyAdj;
21237                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21238                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21239                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21240                                    + ")");
21241                            if (curEmptyAdj != nextEmptyAdj) {
21242                                stepEmpty++;
21243                                if (stepEmpty >= emptyFactor) {
21244                                    stepEmpty = 0;
21245                                    curEmptyAdj = nextEmptyAdj;
21246                                    nextEmptyAdj += 2;
21247                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21248                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21249                                    }
21250                                }
21251                            }
21252                            break;
21253                    }
21254                }
21255
21256                applyOomAdjLocked(app, true, now, nowElapsed);
21257
21258                // Count the number of process types.
21259                switch (app.curProcState) {
21260                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21261                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21262                        mNumCachedHiddenProcs++;
21263                        numCached++;
21264                        if (numCached > cachedProcessLimit) {
21265                            app.kill("cached #" + numCached, true);
21266                        }
21267                        break;
21268                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21269                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21270                                && app.lastActivityTime < oldTime) {
21271                            app.kill("empty for "
21272                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21273                                    / 1000) + "s", true);
21274                        } else {
21275                            numEmpty++;
21276                            if (numEmpty > emptyProcessLimit) {
21277                                app.kill("empty #" + numEmpty, true);
21278                            }
21279                        }
21280                        break;
21281                    default:
21282                        mNumNonCachedProcs++;
21283                        break;
21284                }
21285
21286                if (app.isolated && app.services.size() <= 0) {
21287                    // If this is an isolated process, and there are no
21288                    // services running in it, then the process is no longer
21289                    // needed.  We agressively kill these because we can by
21290                    // definition not re-use the same process again, and it is
21291                    // good to avoid having whatever code was running in them
21292                    // left sitting around after no longer needed.
21293                    app.kill("isolated not needed", true);
21294                } else {
21295                    // Keeping this process, update its uid.
21296                    final UidRecord uidRec = app.uidRecord;
21297                    if (uidRec != null) {
21298                        uidRec.ephemeral = app.info.isEphemeralApp();
21299                        if (uidRec.curProcState > app.curProcState) {
21300                            uidRec.curProcState = app.curProcState;
21301                        }
21302                    }
21303                }
21304
21305                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21306                        && !app.killedByAm) {
21307                    numTrimming++;
21308                }
21309            }
21310        }
21311
21312        mNumServiceProcs = mNewNumServiceProcs;
21313
21314        // Now determine the memory trimming level of background processes.
21315        // Unfortunately we need to start at the back of the list to do this
21316        // properly.  We only do this if the number of background apps we
21317        // are managing to keep around is less than half the maximum we desire;
21318        // if we are keeping a good number around, we'll let them use whatever
21319        // memory they want.
21320        final int numCachedAndEmpty = numCached + numEmpty;
21321        int memFactor;
21322        if (numCached <= ProcessList.TRIM_CACHED_APPS
21323                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21324            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21325                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21326            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21327                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21328            } else {
21329                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21330            }
21331        } else {
21332            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21333        }
21334        // We always allow the memory level to go up (better).  We only allow it to go
21335        // down if we are in a state where that is allowed, *and* the total number of processes
21336        // has gone down since last time.
21337        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21338                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21339                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21340        if (memFactor > mLastMemoryLevel) {
21341            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21342                memFactor = mLastMemoryLevel;
21343                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21344            }
21345        }
21346        if (memFactor != mLastMemoryLevel) {
21347            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21348        }
21349        mLastMemoryLevel = memFactor;
21350        mLastNumProcesses = mLruProcesses.size();
21351        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21352        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21353        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21354            if (mLowRamStartTime == 0) {
21355                mLowRamStartTime = now;
21356            }
21357            int step = 0;
21358            int fgTrimLevel;
21359            switch (memFactor) {
21360                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21361                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21362                    break;
21363                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21364                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21365                    break;
21366                default:
21367                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21368                    break;
21369            }
21370            int factor = numTrimming/3;
21371            int minFactor = 2;
21372            if (mHomeProcess != null) minFactor++;
21373            if (mPreviousProcess != null) minFactor++;
21374            if (factor < minFactor) factor = minFactor;
21375            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21376            for (int i=N-1; i>=0; i--) {
21377                ProcessRecord app = mLruProcesses.get(i);
21378                if (allChanged || app.procStateChanged) {
21379                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21380                    app.procStateChanged = false;
21381                }
21382                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21383                        && !app.killedByAm) {
21384                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21385                        try {
21386                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21387                                    "Trimming memory of " + app.processName + " to " + curLevel);
21388                            app.thread.scheduleTrimMemory(curLevel);
21389                        } catch (RemoteException e) {
21390                        }
21391                        if (false) {
21392                            // For now we won't do this; our memory trimming seems
21393                            // to be good enough at this point that destroying
21394                            // activities causes more harm than good.
21395                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21396                                    && app != mHomeProcess && app != mPreviousProcess) {
21397                                // Need to do this on its own message because the stack may not
21398                                // be in a consistent state at this point.
21399                                // For these apps we will also finish their activities
21400                                // to help them free memory.
21401                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21402                            }
21403                        }
21404                    }
21405                    app.trimMemoryLevel = curLevel;
21406                    step++;
21407                    if (step >= factor) {
21408                        step = 0;
21409                        switch (curLevel) {
21410                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21411                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21412                                break;
21413                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21414                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21415                                break;
21416                        }
21417                    }
21418                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21419                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21420                            && app.thread != null) {
21421                        try {
21422                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21423                                    "Trimming memory of heavy-weight " + app.processName
21424                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21425                            app.thread.scheduleTrimMemory(
21426                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21427                        } catch (RemoteException e) {
21428                        }
21429                    }
21430                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21431                } else {
21432                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21433                            || app.systemNoUi) && app.pendingUiClean) {
21434                        // If this application is now in the background and it
21435                        // had done UI, then give it the special trim level to
21436                        // have it free UI resources.
21437                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21438                        if (app.trimMemoryLevel < level && app.thread != null) {
21439                            try {
21440                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21441                                        "Trimming memory of bg-ui " + app.processName
21442                                        + " to " + level);
21443                                app.thread.scheduleTrimMemory(level);
21444                            } catch (RemoteException e) {
21445                            }
21446                        }
21447                        app.pendingUiClean = false;
21448                    }
21449                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21450                        try {
21451                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21452                                    "Trimming memory of fg " + app.processName
21453                                    + " to " + fgTrimLevel);
21454                            app.thread.scheduleTrimMemory(fgTrimLevel);
21455                        } catch (RemoteException e) {
21456                        }
21457                    }
21458                    app.trimMemoryLevel = fgTrimLevel;
21459                }
21460            }
21461        } else {
21462            if (mLowRamStartTime != 0) {
21463                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21464                mLowRamStartTime = 0;
21465            }
21466            for (int i=N-1; i>=0; i--) {
21467                ProcessRecord app = mLruProcesses.get(i);
21468                if (allChanged || app.procStateChanged) {
21469                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21470                    app.procStateChanged = false;
21471                }
21472                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21473                        || app.systemNoUi) && app.pendingUiClean) {
21474                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21475                            && app.thread != null) {
21476                        try {
21477                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21478                                    "Trimming memory of ui hidden " + app.processName
21479                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21480                            app.thread.scheduleTrimMemory(
21481                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21482                        } catch (RemoteException e) {
21483                        }
21484                    }
21485                    app.pendingUiClean = false;
21486                }
21487                app.trimMemoryLevel = 0;
21488            }
21489        }
21490
21491        if (mAlwaysFinishActivities) {
21492            // Need to do this on its own message because the stack may not
21493            // be in a consistent state at this point.
21494            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21495        }
21496
21497        if (allChanged) {
21498            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21499        }
21500
21501        // Update from any uid changes.
21502        if (mLocalPowerManager != null) {
21503            mLocalPowerManager.startUidChanges();
21504        }
21505        for (int i=mActiveUids.size()-1; i>=0; i--) {
21506            final UidRecord uidRec = mActiveUids.valueAt(i);
21507            int uidChange = UidRecord.CHANGE_PROCSTATE;
21508            if (uidRec.setProcState != uidRec.curProcState) {
21509                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21510                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21511                        + " to " + uidRec.curProcState);
21512                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21513                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21514                        uidRec.lastBackgroundTime = nowElapsed;
21515                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21516                            // Note: the background settle time is in elapsed realtime, while
21517                            // the handler time base is uptime.  All this means is that we may
21518                            // stop background uids later than we had intended, but that only
21519                            // happens because the device was sleeping so we are okay anyway.
21520                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21521                        }
21522                    }
21523                } else {
21524                    if (uidRec.idle) {
21525                        uidChange = UidRecord.CHANGE_ACTIVE;
21526                        uidRec.idle = false;
21527                    }
21528                    uidRec.lastBackgroundTime = 0;
21529                }
21530                uidRec.setProcState = uidRec.curProcState;
21531                enqueueUidChangeLocked(uidRec, -1, uidChange);
21532                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21533            }
21534        }
21535        if (mLocalPowerManager != null) {
21536            mLocalPowerManager.finishUidChanges();
21537        }
21538
21539        if (mProcessStats.shouldWriteNowLocked(now)) {
21540            mHandler.post(new Runnable() {
21541                @Override public void run() {
21542                    synchronized (ActivityManagerService.this) {
21543                        mProcessStats.writeStateAsyncLocked();
21544                    }
21545                }
21546            });
21547        }
21548
21549        if (DEBUG_OOM_ADJ) {
21550            final long duration = SystemClock.uptimeMillis() - now;
21551            if (false) {
21552                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21553                        new RuntimeException("here").fillInStackTrace());
21554            } else {
21555                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21556            }
21557        }
21558    }
21559
21560    @Override
21561    public void makePackageIdle(String packageName, int userId) {
21562        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
21563                != PackageManager.PERMISSION_GRANTED) {
21564            String msg = "Permission Denial: makePackageIdle() from pid="
21565                    + Binder.getCallingPid()
21566                    + ", uid=" + Binder.getCallingUid()
21567                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
21568            Slog.w(TAG, msg);
21569            throw new SecurityException(msg);
21570        }
21571        final int callingPid = Binder.getCallingPid();
21572        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
21573                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
21574        long callingId = Binder.clearCallingIdentity();
21575        synchronized(this) {
21576            try {
21577                IPackageManager pm = AppGlobals.getPackageManager();
21578                int pkgUid = -1;
21579                try {
21580                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
21581                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
21582                } catch (RemoteException e) {
21583                }
21584                if (pkgUid == -1) {
21585                    throw new IllegalArgumentException("Unknown package name " + packageName);
21586                }
21587
21588                if (mLocalPowerManager != null) {
21589                    mLocalPowerManager.startUidChanges();
21590                }
21591                final int appId = UserHandle.getAppId(pkgUid);
21592                final int N = mActiveUids.size();
21593                for (int i=N-1; i>=0; i--) {
21594                    final UidRecord uidRec = mActiveUids.valueAt(i);
21595                    final long bgTime = uidRec.lastBackgroundTime;
21596                    if (bgTime > 0 && !uidRec.idle) {
21597                        if (UserHandle.getAppId(uidRec.uid) == appId) {
21598                            if (userId == UserHandle.USER_ALL ||
21599                                    userId == UserHandle.getUserId(uidRec.uid)) {
21600                                uidRec.idle = true;
21601                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
21602                                        + " from package " + packageName + " user " + userId);
21603                                doStopUidLocked(uidRec.uid, uidRec);
21604                            }
21605                        }
21606                    }
21607                }
21608            } finally {
21609                if (mLocalPowerManager != null) {
21610                    mLocalPowerManager.finishUidChanges();
21611                }
21612                Binder.restoreCallingIdentity(callingId);
21613            }
21614        }
21615    }
21616
21617    final void idleUids() {
21618        synchronized (this) {
21619            final int N = mActiveUids.size();
21620            if (N <= 0) {
21621                return;
21622            }
21623            final long nowElapsed = SystemClock.elapsedRealtime();
21624            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21625            long nextTime = 0;
21626            if (mLocalPowerManager != null) {
21627                mLocalPowerManager.startUidChanges();
21628            }
21629            for (int i=N-1; i>=0; i--) {
21630                final UidRecord uidRec = mActiveUids.valueAt(i);
21631                final long bgTime = uidRec.lastBackgroundTime;
21632                if (bgTime > 0 && !uidRec.idle) {
21633                    if (bgTime <= maxBgTime) {
21634                        uidRec.idle = true;
21635                        doStopUidLocked(uidRec.uid, uidRec);
21636                    } else {
21637                        if (nextTime == 0 || nextTime > bgTime) {
21638                            nextTime = bgTime;
21639                        }
21640                    }
21641                }
21642            }
21643            if (mLocalPowerManager != null) {
21644                mLocalPowerManager.finishUidChanges();
21645            }
21646            if (nextTime > 0) {
21647                mHandler.removeMessages(IDLE_UIDS_MSG);
21648                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21649                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21650            }
21651        }
21652    }
21653
21654    final void runInBackgroundDisabled(int uid) {
21655        synchronized (this) {
21656            UidRecord uidRec = mActiveUids.get(uid);
21657            if (uidRec != null) {
21658                // This uid is actually running...  should it be considered background now?
21659                if (uidRec.idle) {
21660                    doStopUidLocked(uidRec.uid, uidRec);
21661                }
21662            } else {
21663                // This uid isn't actually running...  still send a report about it being "stopped".
21664                doStopUidLocked(uid, null);
21665            }
21666        }
21667    }
21668
21669    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21670        mServices.stopInBackgroundLocked(uid);
21671        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21672    }
21673
21674    final void trimApplications() {
21675        synchronized (this) {
21676            int i;
21677
21678            // First remove any unused application processes whose package
21679            // has been removed.
21680            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21681                final ProcessRecord app = mRemovedProcesses.get(i);
21682                if (app.activities.size() == 0
21683                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21684                    Slog.i(
21685                        TAG, "Exiting empty application process "
21686                        + app.toShortString() + " ("
21687                        + (app.thread != null ? app.thread.asBinder() : null)
21688                        + ")\n");
21689                    if (app.pid > 0 && app.pid != MY_PID) {
21690                        app.kill("empty", false);
21691                    } else {
21692                        try {
21693                            app.thread.scheduleExit();
21694                        } catch (Exception e) {
21695                            // Ignore exceptions.
21696                        }
21697                    }
21698                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21699                    mRemovedProcesses.remove(i);
21700
21701                    if (app.persistent) {
21702                        addAppLocked(app.info, false, null /* ABI override */);
21703                    }
21704                }
21705            }
21706
21707            // Now update the oom adj for all processes.
21708            updateOomAdjLocked();
21709        }
21710    }
21711
21712    /** This method sends the specified signal to each of the persistent apps */
21713    public void signalPersistentProcesses(int sig) throws RemoteException {
21714        if (sig != Process.SIGNAL_USR1) {
21715            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21716        }
21717
21718        synchronized (this) {
21719            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21720                    != PackageManager.PERMISSION_GRANTED) {
21721                throw new SecurityException("Requires permission "
21722                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21723            }
21724
21725            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21726                ProcessRecord r = mLruProcesses.get(i);
21727                if (r.thread != null && r.persistent) {
21728                    Process.sendSignal(r.pid, sig);
21729                }
21730            }
21731        }
21732    }
21733
21734    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21735        if (proc == null || proc == mProfileProc) {
21736            proc = mProfileProc;
21737            profileType = mProfileType;
21738            clearProfilerLocked();
21739        }
21740        if (proc == null) {
21741            return;
21742        }
21743        try {
21744            proc.thread.profilerControl(false, null, profileType);
21745        } catch (RemoteException e) {
21746            throw new IllegalStateException("Process disappeared");
21747        }
21748    }
21749
21750    private void clearProfilerLocked() {
21751        if (mProfileFd != null) {
21752            try {
21753                mProfileFd.close();
21754            } catch (IOException e) {
21755            }
21756        }
21757        mProfileApp = null;
21758        mProfileProc = null;
21759        mProfileFile = null;
21760        mProfileType = 0;
21761        mAutoStopProfiler = false;
21762        mSamplingInterval = 0;
21763    }
21764
21765    public boolean profileControl(String process, int userId, boolean start,
21766            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21767
21768        try {
21769            synchronized (this) {
21770                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21771                // its own permission.
21772                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21773                        != PackageManager.PERMISSION_GRANTED) {
21774                    throw new SecurityException("Requires permission "
21775                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21776                }
21777
21778                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21779                    throw new IllegalArgumentException("null profile info or fd");
21780                }
21781
21782                ProcessRecord proc = null;
21783                if (process != null) {
21784                    proc = findProcessLocked(process, userId, "profileControl");
21785                }
21786
21787                if (start && (proc == null || proc.thread == null)) {
21788                    throw new IllegalArgumentException("Unknown process: " + process);
21789                }
21790
21791                if (start) {
21792                    stopProfilerLocked(null, 0);
21793                    setProfileApp(proc.info, proc.processName, profilerInfo);
21794                    mProfileProc = proc;
21795                    mProfileType = profileType;
21796                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21797                    try {
21798                        fd = fd.dup();
21799                    } catch (IOException e) {
21800                        fd = null;
21801                    }
21802                    profilerInfo.profileFd = fd;
21803                    proc.thread.profilerControl(start, profilerInfo, profileType);
21804                    fd = null;
21805                    mProfileFd = null;
21806                } else {
21807                    stopProfilerLocked(proc, profileType);
21808                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21809                        try {
21810                            profilerInfo.profileFd.close();
21811                        } catch (IOException e) {
21812                        }
21813                    }
21814                }
21815
21816                return true;
21817            }
21818        } catch (RemoteException e) {
21819            throw new IllegalStateException("Process disappeared");
21820        } finally {
21821            if (profilerInfo != null && profilerInfo.profileFd != null) {
21822                try {
21823                    profilerInfo.profileFd.close();
21824                } catch (IOException e) {
21825                }
21826            }
21827        }
21828    }
21829
21830    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21831        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21832                userId, true, ALLOW_FULL_ONLY, callName, null);
21833        ProcessRecord proc = null;
21834        try {
21835            int pid = Integer.parseInt(process);
21836            synchronized (mPidsSelfLocked) {
21837                proc = mPidsSelfLocked.get(pid);
21838            }
21839        } catch (NumberFormatException e) {
21840        }
21841
21842        if (proc == null) {
21843            ArrayMap<String, SparseArray<ProcessRecord>> all
21844                    = mProcessNames.getMap();
21845            SparseArray<ProcessRecord> procs = all.get(process);
21846            if (procs != null && procs.size() > 0) {
21847                proc = procs.valueAt(0);
21848                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21849                    for (int i=1; i<procs.size(); i++) {
21850                        ProcessRecord thisProc = procs.valueAt(i);
21851                        if (thisProc.userId == userId) {
21852                            proc = thisProc;
21853                            break;
21854                        }
21855                    }
21856                }
21857            }
21858        }
21859
21860        return proc;
21861    }
21862
21863    public boolean dumpHeap(String process, int userId, boolean managed,
21864            String path, ParcelFileDescriptor fd) throws RemoteException {
21865
21866        try {
21867            synchronized (this) {
21868                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21869                // its own permission (same as profileControl).
21870                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21871                        != PackageManager.PERMISSION_GRANTED) {
21872                    throw new SecurityException("Requires permission "
21873                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21874                }
21875
21876                if (fd == null) {
21877                    throw new IllegalArgumentException("null fd");
21878                }
21879
21880                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21881                if (proc == null || proc.thread == null) {
21882                    throw new IllegalArgumentException("Unknown process: " + process);
21883                }
21884
21885                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21886                if (!isDebuggable) {
21887                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21888                        throw new SecurityException("Process not debuggable: " + proc);
21889                    }
21890                }
21891
21892                proc.thread.dumpHeap(managed, path, fd);
21893                fd = null;
21894                return true;
21895            }
21896        } catch (RemoteException e) {
21897            throw new IllegalStateException("Process disappeared");
21898        } finally {
21899            if (fd != null) {
21900                try {
21901                    fd.close();
21902                } catch (IOException e) {
21903                }
21904            }
21905        }
21906    }
21907
21908    @Override
21909    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21910            String reportPackage) {
21911        if (processName != null) {
21912            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21913                    "setDumpHeapDebugLimit()");
21914        } else {
21915            synchronized (mPidsSelfLocked) {
21916                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21917                if (proc == null) {
21918                    throw new SecurityException("No process found for calling pid "
21919                            + Binder.getCallingPid());
21920                }
21921                if (!Build.IS_DEBUGGABLE
21922                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21923                    throw new SecurityException("Not running a debuggable build");
21924                }
21925                processName = proc.processName;
21926                uid = proc.uid;
21927                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21928                    throw new SecurityException("Package " + reportPackage + " is not running in "
21929                            + proc);
21930                }
21931            }
21932        }
21933        synchronized (this) {
21934            if (maxMemSize > 0) {
21935                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21936            } else {
21937                if (uid != 0) {
21938                    mMemWatchProcesses.remove(processName, uid);
21939                } else {
21940                    mMemWatchProcesses.getMap().remove(processName);
21941                }
21942            }
21943        }
21944    }
21945
21946    @Override
21947    public void dumpHeapFinished(String path) {
21948        synchronized (this) {
21949            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21950                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21951                        + " does not match last pid " + mMemWatchDumpPid);
21952                return;
21953            }
21954            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21955                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21956                        + " does not match last path " + mMemWatchDumpFile);
21957                return;
21958            }
21959            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21960            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21961        }
21962    }
21963
21964    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21965    public void monitor() {
21966        synchronized (this) { }
21967    }
21968
21969    void onCoreSettingsChange(Bundle settings) {
21970        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21971            ProcessRecord processRecord = mLruProcesses.get(i);
21972            try {
21973                if (processRecord.thread != null) {
21974                    processRecord.thread.setCoreSettings(settings);
21975                }
21976            } catch (RemoteException re) {
21977                /* ignore */
21978            }
21979        }
21980    }
21981
21982    // Multi-user methods
21983
21984    /**
21985     * Start user, if its not already running, but don't bring it to foreground.
21986     */
21987    @Override
21988    public boolean startUserInBackground(final int userId) {
21989        return mUserController.startUser(userId, /* foreground */ false);
21990    }
21991
21992    @Override
21993    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21994        return mUserController.unlockUser(userId, token, secret, listener);
21995    }
21996
21997    @Override
21998    public boolean switchUser(final int targetUserId) {
21999        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
22000        int currentUserId;
22001        UserInfo targetUserInfo;
22002        synchronized (this) {
22003            currentUserId = mUserController.getCurrentUserIdLocked();
22004            targetUserInfo = mUserController.getUserInfo(targetUserId);
22005            if (targetUserId == currentUserId) {
22006                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
22007                return true;
22008            }
22009            if (targetUserInfo == null) {
22010                Slog.w(TAG, "No user info for user #" + targetUserId);
22011                return false;
22012            }
22013            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
22014                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
22015                        + " when device is in demo mode");
22016                return false;
22017            }
22018            if (!targetUserInfo.supportsSwitchTo()) {
22019                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
22020                return false;
22021            }
22022            if (targetUserInfo.isManagedProfile()) {
22023                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
22024                return false;
22025            }
22026            mUserController.setTargetUserIdLocked(targetUserId);
22027        }
22028        if (mUserController.mUserSwitchUiEnabled) {
22029            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
22030            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
22031            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
22032            mUiHandler.sendMessage(mHandler.obtainMessage(
22033                    START_USER_SWITCH_UI_MSG, userNames));
22034        } else {
22035            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
22036            mHandler.sendMessage(mHandler.obtainMessage(
22037                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
22038        }
22039        return true;
22040    }
22041
22042    void scheduleStartProfilesLocked() {
22043        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
22044            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
22045                    DateUtils.SECOND_IN_MILLIS);
22046        }
22047    }
22048
22049    @Override
22050    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
22051        return mUserController.stopUser(userId, force, callback);
22052    }
22053
22054    @Override
22055    public UserInfo getCurrentUser() {
22056        return mUserController.getCurrentUser();
22057    }
22058
22059    String getStartedUserState(int userId) {
22060        synchronized (this) {
22061            final UserState userState = mUserController.getStartedUserStateLocked(userId);
22062            return UserState.stateToString(userState.state);
22063        }
22064    }
22065
22066    @Override
22067    public boolean isUserRunning(int userId, int flags) {
22068        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
22069                && checkCallingPermission(INTERACT_ACROSS_USERS)
22070                    != PackageManager.PERMISSION_GRANTED) {
22071            String msg = "Permission Denial: isUserRunning() from pid="
22072                    + Binder.getCallingPid()
22073                    + ", uid=" + Binder.getCallingUid()
22074                    + " requires " + INTERACT_ACROSS_USERS;
22075            Slog.w(TAG, msg);
22076            throw new SecurityException(msg);
22077        }
22078        synchronized (this) {
22079            return mUserController.isUserRunningLocked(userId, flags);
22080        }
22081    }
22082
22083    @Override
22084    public int[] getRunningUserIds() {
22085        if (checkCallingPermission(INTERACT_ACROSS_USERS)
22086                != PackageManager.PERMISSION_GRANTED) {
22087            String msg = "Permission Denial: isUserRunning() from pid="
22088                    + Binder.getCallingPid()
22089                    + ", uid=" + Binder.getCallingUid()
22090                    + " requires " + INTERACT_ACROSS_USERS;
22091            Slog.w(TAG, msg);
22092            throw new SecurityException(msg);
22093        }
22094        synchronized (this) {
22095            return mUserController.getStartedUserArrayLocked();
22096        }
22097    }
22098
22099    @Override
22100    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
22101        mUserController.registerUserSwitchObserver(observer, name);
22102    }
22103
22104    @Override
22105    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
22106        mUserController.unregisterUserSwitchObserver(observer);
22107    }
22108
22109    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
22110        if (info == null) return null;
22111        ApplicationInfo newInfo = new ApplicationInfo(info);
22112        newInfo.initForUser(userId);
22113        return newInfo;
22114    }
22115
22116    public boolean isUserStopped(int userId) {
22117        synchronized (this) {
22118            return mUserController.getStartedUserStateLocked(userId) == null;
22119        }
22120    }
22121
22122    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
22123        if (aInfo == null
22124                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
22125            return aInfo;
22126        }
22127
22128        ActivityInfo info = new ActivityInfo(aInfo);
22129        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
22130        return info;
22131    }
22132
22133    private boolean processSanityChecksLocked(ProcessRecord process) {
22134        if (process == null || process.thread == null) {
22135            return false;
22136        }
22137
22138        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22139        if (!isDebuggable) {
22140            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22141                return false;
22142            }
22143        }
22144
22145        return true;
22146    }
22147
22148    public boolean startBinderTracking() throws RemoteException {
22149        synchronized (this) {
22150            mBinderTransactionTrackingEnabled = true;
22151            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22152            // permission (same as profileControl).
22153            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22154                    != PackageManager.PERMISSION_GRANTED) {
22155                throw new SecurityException("Requires permission "
22156                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22157            }
22158
22159            for (int i = 0; i < mLruProcesses.size(); i++) {
22160                ProcessRecord process = mLruProcesses.get(i);
22161                if (!processSanityChecksLocked(process)) {
22162                    continue;
22163                }
22164                try {
22165                    process.thread.startBinderTracking();
22166                } catch (RemoteException e) {
22167                    Log.v(TAG, "Process disappared");
22168                }
22169            }
22170            return true;
22171        }
22172    }
22173
22174    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
22175        try {
22176            synchronized (this) {
22177                mBinderTransactionTrackingEnabled = false;
22178                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22179                // permission (same as profileControl).
22180                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22181                        != PackageManager.PERMISSION_GRANTED) {
22182                    throw new SecurityException("Requires permission "
22183                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22184                }
22185
22186                if (fd == null) {
22187                    throw new IllegalArgumentException("null fd");
22188                }
22189
22190                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
22191                pw.println("Binder transaction traces for all processes.\n");
22192                for (ProcessRecord process : mLruProcesses) {
22193                    if (!processSanityChecksLocked(process)) {
22194                        continue;
22195                    }
22196
22197                    pw.println("Traces for process: " + process.processName);
22198                    pw.flush();
22199                    try {
22200                        TransferPipe tp = new TransferPipe();
22201                        try {
22202                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
22203                            tp.go(fd.getFileDescriptor());
22204                        } finally {
22205                            tp.kill();
22206                        }
22207                    } catch (IOException e) {
22208                        pw.println("Failure while dumping IPC traces from " + process +
22209                                ".  Exception: " + e);
22210                        pw.flush();
22211                    } catch (RemoteException e) {
22212                        pw.println("Got a RemoteException while dumping IPC traces from " +
22213                                process + ".  Exception: " + e);
22214                        pw.flush();
22215                    }
22216                }
22217                fd = null;
22218                return true;
22219            }
22220        } finally {
22221            if (fd != null) {
22222                try {
22223                    fd.close();
22224                } catch (IOException e) {
22225                }
22226            }
22227        }
22228    }
22229
22230    private final class LocalService extends ActivityManagerInternal {
22231        @Override
22232        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
22233                int targetUserId) {
22234            synchronized (ActivityManagerService.this) {
22235                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
22236                        targetPkg, intent, null, targetUserId);
22237            }
22238        }
22239
22240        @Override
22241        public String checkContentProviderAccess(String authority, int userId) {
22242            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
22243        }
22244
22245        @Override
22246        public void onWakefulnessChanged(int wakefulness) {
22247            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22248        }
22249
22250        @Override
22251        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22252                String processName, String abiOverride, int uid, Runnable crashHandler) {
22253            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22254                    processName, abiOverride, uid, crashHandler);
22255        }
22256
22257        @Override
22258        public SleepToken acquireSleepToken(String tag) {
22259            Preconditions.checkNotNull(tag);
22260
22261            synchronized (ActivityManagerService.this) {
22262                SleepTokenImpl token = new SleepTokenImpl(tag);
22263                mSleepTokens.add(token);
22264                updateSleepIfNeededLocked();
22265                return token;
22266            }
22267        }
22268
22269        @Override
22270        public ComponentName getHomeActivityForUser(int userId) {
22271            synchronized (ActivityManagerService.this) {
22272                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22273                return homeActivity == null ? null : homeActivity.realActivity;
22274            }
22275        }
22276
22277        @Override
22278        public void onUserRemoved(int userId) {
22279            synchronized (ActivityManagerService.this) {
22280                ActivityManagerService.this.onUserStoppedLocked(userId);
22281            }
22282        }
22283
22284        @Override
22285        public void onLocalVoiceInteractionStarted(IBinder activity,
22286                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22287            synchronized (ActivityManagerService.this) {
22288                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22289                        voiceSession, voiceInteractor);
22290            }
22291        }
22292
22293        @Override
22294        public void notifyStartingWindowDrawn() {
22295            synchronized (ActivityManagerService.this) {
22296                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22297            }
22298        }
22299
22300        @Override
22301        public void notifyAppTransitionStarting(int reason) {
22302            synchronized (ActivityManagerService.this) {
22303                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22304            }
22305        }
22306
22307        @Override
22308        public void notifyAppTransitionFinished() {
22309            synchronized (ActivityManagerService.this) {
22310                mStackSupervisor.notifyAppTransitionDone();
22311            }
22312        }
22313
22314        @Override
22315        public void notifyAppTransitionCancelled() {
22316            synchronized (ActivityManagerService.this) {
22317                mStackSupervisor.notifyAppTransitionDone();
22318            }
22319        }
22320
22321        @Override
22322        public List<IBinder> getTopVisibleActivities() {
22323            synchronized (ActivityManagerService.this) {
22324                return mStackSupervisor.getTopVisibleActivities();
22325            }
22326        }
22327
22328        @Override
22329        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22330            synchronized (ActivityManagerService.this) {
22331                mStackSupervisor.setDockedStackMinimized(minimized);
22332            }
22333        }
22334
22335        @Override
22336        public void killForegroundAppsForUser(int userHandle) {
22337            synchronized (ActivityManagerService.this) {
22338                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22339                final int NP = mProcessNames.getMap().size();
22340                for (int ip = 0; ip < NP; ip++) {
22341                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22342                    final int NA = apps.size();
22343                    for (int ia = 0; ia < NA; ia++) {
22344                        final ProcessRecord app = apps.valueAt(ia);
22345                        if (app.persistent) {
22346                            // We don't kill persistent processes.
22347                            continue;
22348                        }
22349                        if (app.removed) {
22350                            procs.add(app);
22351                        } else if (app.userId == userHandle && app.foregroundActivities) {
22352                            app.removed = true;
22353                            procs.add(app);
22354                        }
22355                    }
22356                }
22357
22358                final int N = procs.size();
22359                for (int i = 0; i < N; i++) {
22360                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22361                }
22362            }
22363        }
22364
22365        @Override
22366        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22367            if (!(target instanceof PendingIntentRecord)) {
22368                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22369                return;
22370            }
22371            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22372        }
22373
22374        @Override
22375        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22376                int userId) {
22377            Preconditions.checkNotNull(values, "Configuration must not be null");
22378            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22379            synchronized (ActivityManagerService.this) {
22380                updateConfigurationLocked(values, null, false, true, userId,
22381                        false /* deferResume */);
22382            }
22383        }
22384
22385        @Override
22386        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22387                Bundle bOptions) {
22388            Preconditions.checkNotNull(intents, "intents");
22389            final String[] resolvedTypes = new String[intents.length];
22390            for (int i = 0; i < intents.length; i++) {
22391                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22392            }
22393
22394            // UID of the package on user userId.
22395            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22396            // packageUid may not be initialized.
22397            int packageUid = 0;
22398            try {
22399                packageUid = AppGlobals.getPackageManager().getPackageUid(
22400                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22401            } catch (RemoteException e) {
22402                // Shouldn't happen.
22403            }
22404
22405            synchronized (ActivityManagerService.this) {
22406                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22407                        /*resultTo*/ null, bOptions, userId);
22408            }
22409        }
22410
22411        @Override
22412        public int getUidProcessState(int uid) {
22413            return getUidState(uid);
22414        }
22415
22416        @Override
22417        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
22418            synchronized (ActivityManagerService.this) {
22419
22420                // We might change the visibilities here, so prepare an empty app transition which
22421                // might be overridden later if we actually change visibilities.
22422                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
22423                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22424                mWindowManager.executeAppTransition();
22425            }
22426            if (callback != null) {
22427                callback.run();
22428            }
22429        }
22430
22431        @Override
22432        public boolean isSystemReady() {
22433            // no need to synchronize(this) just to read & return the value
22434            return mSystemReady;
22435        }
22436
22437        @Override
22438        public void notifyKeyguardTrustedChanged() {
22439            synchronized (ActivityManagerService.this) {
22440                if (mKeyguardController.isKeyguardShowing()) {
22441                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22442                }
22443            }
22444        }
22445    }
22446
22447    private final class SleepTokenImpl extends SleepToken {
22448        private final String mTag;
22449        private final long mAcquireTime;
22450
22451        public SleepTokenImpl(String tag) {
22452            mTag = tag;
22453            mAcquireTime = SystemClock.uptimeMillis();
22454        }
22455
22456        @Override
22457        public void release() {
22458            synchronized (ActivityManagerService.this) {
22459                if (mSleepTokens.remove(this)) {
22460                    updateSleepIfNeededLocked();
22461                }
22462            }
22463        }
22464
22465        @Override
22466        public String toString() {
22467            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22468        }
22469    }
22470
22471    /**
22472     * An implementation of IAppTask, that allows an app to manage its own tasks via
22473     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22474     * only the process that calls getAppTasks() can call the AppTask methods.
22475     */
22476    class AppTaskImpl extends IAppTask.Stub {
22477        private int mTaskId;
22478        private int mCallingUid;
22479
22480        public AppTaskImpl(int taskId, int callingUid) {
22481            mTaskId = taskId;
22482            mCallingUid = callingUid;
22483        }
22484
22485        private void checkCaller() {
22486            if (mCallingUid != Binder.getCallingUid()) {
22487                throw new SecurityException("Caller " + mCallingUid
22488                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22489            }
22490        }
22491
22492        @Override
22493        public void finishAndRemoveTask() {
22494            checkCaller();
22495
22496            synchronized (ActivityManagerService.this) {
22497                long origId = Binder.clearCallingIdentity();
22498                try {
22499                    // We remove the task from recents to preserve backwards
22500                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
22501                            REMOVE_FROM_RECENTS)) {
22502                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22503                    }
22504                } finally {
22505                    Binder.restoreCallingIdentity(origId);
22506                }
22507            }
22508        }
22509
22510        @Override
22511        public ActivityManager.RecentTaskInfo getTaskInfo() {
22512            checkCaller();
22513
22514            synchronized (ActivityManagerService.this) {
22515                long origId = Binder.clearCallingIdentity();
22516                try {
22517                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22518                    if (tr == null) {
22519                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22520                    }
22521                    return createRecentTaskInfoFromTaskRecord(tr);
22522                } finally {
22523                    Binder.restoreCallingIdentity(origId);
22524                }
22525            }
22526        }
22527
22528        @Override
22529        public void moveToFront() {
22530            checkCaller();
22531            // Will bring task to front if it already has a root activity.
22532            final long origId = Binder.clearCallingIdentity();
22533            try {
22534                synchronized (this) {
22535                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22536                }
22537            } finally {
22538                Binder.restoreCallingIdentity(origId);
22539            }
22540        }
22541
22542        @Override
22543        public int startActivity(IBinder whoThread, String callingPackage,
22544                Intent intent, String resolvedType, Bundle bOptions) {
22545            checkCaller();
22546
22547            int callingUser = UserHandle.getCallingUserId();
22548            TaskRecord tr;
22549            IApplicationThread appThread;
22550            synchronized (ActivityManagerService.this) {
22551                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22552                if (tr == null) {
22553                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22554                }
22555                appThread = IApplicationThread.Stub.asInterface(whoThread);
22556                if (appThread == null) {
22557                    throw new IllegalArgumentException("Bad app thread " + appThread);
22558                }
22559            }
22560            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22561                    resolvedType, null, null, null, null, 0, 0, null, null,
22562                    null, bOptions, false, callingUser, null, tr);
22563        }
22564
22565        @Override
22566        public void setExcludeFromRecents(boolean exclude) {
22567            checkCaller();
22568
22569            synchronized (ActivityManagerService.this) {
22570                long origId = Binder.clearCallingIdentity();
22571                try {
22572                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22573                    if (tr == null) {
22574                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22575                    }
22576                    Intent intent = tr.getBaseIntent();
22577                    if (exclude) {
22578                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22579                    } else {
22580                        intent.setFlags(intent.getFlags()
22581                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22582                    }
22583                } finally {
22584                    Binder.restoreCallingIdentity(origId);
22585                }
22586            }
22587        }
22588    }
22589
22590    /**
22591     * Kill processes for the user with id userId and that depend on the package named packageName
22592     */
22593    @Override
22594    public void killPackageDependents(String packageName, int userId) {
22595        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22596        if (packageName == null) {
22597            throw new NullPointerException(
22598                    "Cannot kill the dependents of a package without its name.");
22599        }
22600
22601        long callingId = Binder.clearCallingIdentity();
22602        IPackageManager pm = AppGlobals.getPackageManager();
22603        int pkgUid = -1;
22604        try {
22605            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22606        } catch (RemoteException e) {
22607        }
22608        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22609            throw new IllegalArgumentException(
22610                    "Cannot kill dependents of non-existing package " + packageName);
22611        }
22612        try {
22613            synchronized(this) {
22614                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22615                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22616                        "dep: " + packageName);
22617            }
22618        } finally {
22619            Binder.restoreCallingIdentity(callingId);
22620        }
22621    }
22622
22623    @Override
22624    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22625        final int userId = intent.getCreatorUserHandle().getIdentifier();
22626        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22627            return false;
22628        }
22629        IIntentSender target = intent.getTarget();
22630        if (!(target instanceof PendingIntentRecord)) {
22631            return false;
22632        }
22633        final PendingIntentRecord record = (PendingIntentRecord) target;
22634        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22635                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22636        // For direct boot aware activities, they can be shown without triggering a work challenge
22637        // before the profile user is unlocked.
22638        return rInfo != null && rInfo.activityInfo != null;
22639    }
22640
22641    @Override
22642    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
22643            throws RemoteException {
22644        final long callingId = Binder.clearCallingIdentity();
22645        try {
22646            mKeyguardController.dismissKeyguard(token, callback);
22647        } finally {
22648            Binder.restoreCallingIdentity(callingId);
22649        }
22650    }
22651
22652    /**
22653     * Attach an agent to the specified process (proces name or PID)
22654     */
22655    public void attachAgent(String process, String path) {
22656        try {
22657            synchronized (this) {
22658                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22659                if (proc == null || proc.thread == null) {
22660                    throw new IllegalArgumentException("Unknown process: " + process);
22661                }
22662
22663                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22664                if (!isDebuggable) {
22665                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22666                        throw new SecurityException("Process not debuggable: " + proc);
22667                    }
22668                }
22669
22670                proc.thread.attachAgent(path);
22671            }
22672        } catch (RemoteException e) {
22673            throw new IllegalStateException("Process disappeared");
22674        }
22675    }
22676}
22677