ActivityManagerService.java revision e69c93181f1f313dcedd07f677af1cea953fdf16
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.ApplicationThreadConstants;
21import android.app.ContentProviderHolder;
22import android.app.IActivityManager;
23import android.app.WaitResult;
24import android.os.IDeviceIdentifiersPolicyService;
25import android.util.Size;
26import android.util.TypedValue;
27import android.view.DisplayInfo;
28import com.android.internal.telephony.TelephonyIntents;
29import com.google.android.collect.Lists;
30import com.google.android.collect.Maps;
31import com.android.internal.R;
32import com.android.internal.annotations.GuardedBy;
33import com.android.internal.app.AssistUtils;
34import com.android.internal.app.DumpHeapActivity;
35import com.android.internal.app.IAppOpsCallback;
36import com.android.internal.app.IAppOpsService;
37import com.android.internal.app.IVoiceInteractor;
38import com.android.internal.app.ProcessMap;
39import com.android.internal.app.SystemUserHomeActivity;
40import com.android.internal.app.procstats.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.IResultReceiver;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.os.Zygote;
47import com.android.internal.os.InstallerConnection.InstallerException;
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.statusbar.StatusBarManagerInternal;
67import com.android.server.vr.VrManagerInternal;
68import com.android.server.wm.WindowManagerService;
69
70import org.xmlpull.v1.XmlPullParser;
71import org.xmlpull.v1.XmlPullParserException;
72import org.xmlpull.v1.XmlSerializer;
73
74import android.Manifest;
75import android.Manifest.permission;
76import android.annotation.NonNull;
77import android.annotation.UserIdInt;
78import android.app.Activity;
79import android.app.ActivityManager;
80import android.app.ActivityManager.RunningTaskInfo;
81import android.app.ActivityManager.StackId;
82import android.app.ActivityManager.StackInfo;
83import android.app.ActivityManager.TaskDescription;
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.IMountService;
203import android.os.storage.MountServiceInternal;
204import android.os.storage.StorageManager;
205import android.provider.Settings;
206import android.service.voice.IVoiceInteractionSession;
207import android.service.voice.VoiceInteractionManagerInternal;
208import android.service.voice.VoiceInteractionSession;
209import android.telecom.TelecomManager;
210import android.text.format.DateUtils;
211import android.text.format.Time;
212import android.text.style.SuggestionSpan;
213import android.util.ArrayMap;
214import android.util.ArraySet;
215import android.util.AtomicFile;
216import android.util.DebugUtils;
217import android.util.DisplayMetrics;
218import android.util.EventLog;
219import android.util.Log;
220import android.util.Pair;
221import android.util.PrintWriterPrinter;
222import android.util.Slog;
223import android.util.SparseArray;
224import android.util.TimeUtils;
225import android.util.Xml;
226import android.view.Gravity;
227import android.view.LayoutInflater;
228import android.view.View;
229import android.view.WindowManager;
230
231import java.io.File;
232import java.io.FileDescriptor;
233import java.io.FileInputStream;
234import java.io.FileNotFoundException;
235import java.io.FileOutputStream;
236import java.io.IOException;
237import java.io.InputStreamReader;
238import java.io.PrintWriter;
239import java.io.StringWriter;
240import java.lang.ref.WeakReference;
241import java.nio.charset.StandardCharsets;
242import java.util.ArrayList;
243import java.util.Arrays;
244import java.util.Collections;
245import java.util.Comparator;
246import java.util.HashMap;
247import java.util.HashSet;
248import java.util.Iterator;
249import java.util.List;
250import java.util.Locale;
251import java.util.Map;
252import java.util.Objects;
253import java.util.Set;
254import java.util.concurrent.atomic.AtomicBoolean;
255import java.util.concurrent.atomic.AtomicLong;
256
257import dalvik.system.VMRuntime;
258
259import libcore.io.IoUtils;
260import libcore.util.EmptyArray;
261
262import static android.Manifest.permission.CHANGE_CONFIGURATION;
263import static android.Manifest.permission.INTERACT_ACROSS_USERS;
264import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
265import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
266import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
267import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
268import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
269import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
270import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
271import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
272import static android.app.ActivityManager.StackId.HOME_STACK_ID;
273import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
274import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
275import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
276import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
277import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
278import static android.content.pm.PackageManager.GET_PROVIDERS;
279import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
280import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
281import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
282import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
283import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
284import static android.content.pm.PackageManager.PERMISSION_GRANTED;
285import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
286import static android.os.Build.VERSION_CODES.N;
287import static android.os.Process.PROC_CHAR;
288import static android.os.Process.PROC_OUT_LONG;
289import static android.os.Process.PROC_PARENS;
290import static android.os.Process.PROC_SPACE_TERM;
291import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
292import static android.provider.Settings.Global.DEBUG_APP;
293import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
294import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
295import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
296import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
297import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
298import static android.provider.Settings.System.FONT_SCALE;
299import static android.util.TypedValue.COMPLEX_UNIT_DIP;
300import static android.view.Display.DEFAULT_DISPLAY;
301
302import static com.android.internal.util.XmlUtils.readBooleanAttribute;
303import static com.android.internal.util.XmlUtils.readIntAttribute;
304import static com.android.internal.util.XmlUtils.readLongAttribute;
305import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
306import static com.android.internal.util.XmlUtils.writeIntAttribute;
307import static com.android.internal.util.XmlUtils.writeLongAttribute;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
329import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
330import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
331import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
332import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
333import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
334import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
335import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
336import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
337import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
338import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
339import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
353import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
354import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
355import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
356import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
357import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
358import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
359import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
360import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
361import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
362import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
363import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
364import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
365import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
366import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
367import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
368import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
369import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
370import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
371import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
372import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
373import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
374import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
375import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
376import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
377import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
378import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
379import static com.android.server.wm.AppTransition.TRANSIT_NONE;
380import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
381import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
382import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
383import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
384import static org.xmlpull.v1.XmlPullParser.START_TAG;
385
386public class ActivityManagerService extends IActivityManager.Stub
387        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
388
389    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
390    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
391    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
392    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
393    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
394    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
395    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
396    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
397    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
398    private static final String TAG_LRU = TAG + POSTFIX_LRU;
399    private static final String TAG_MU = TAG + POSTFIX_MU;
400    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
401    private static final String TAG_POWER = TAG + POSTFIX_POWER;
402    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
403    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
404    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
405    private static final String TAG_PSS = TAG + POSTFIX_PSS;
406    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
407    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
408    private static final String TAG_STACK = TAG + POSTFIX_STACK;
409    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
410    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
411    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
412    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
413    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
414
415    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
416    // here so that while the job scheduler can depend on AMS, the other way around
417    // need not be the case.
418    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
419
420    /** Control over CPU and battery monitoring */
421    // write battery stats every 30 minutes.
422    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
423    static final boolean MONITOR_CPU_USAGE = true;
424    // don't sample cpu less than every 5 seconds.
425    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
426    // wait possibly forever for next cpu sample.
427    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
428    static final boolean MONITOR_THREAD_CPU_USAGE = false;
429
430    // The flags that are set for all calls we make to the package manager.
431    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
432
433    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
434
435    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
436
437    // Amount of time after a call to stopAppSwitches() during which we will
438    // prevent further untrusted switches from happening.
439    static final long APP_SWITCH_DELAY_TIME = 5*1000;
440
441    // How long we wait for a launched process to attach to the activity manager
442    // before we decide it's never going to come up for real.
443    static final int PROC_START_TIMEOUT = 10*1000;
444    // How long we wait for an attached process to publish its content providers
445    // before we decide it must be hung.
446    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
447
448    // How long we will retain processes hosting content providers in the "last activity"
449    // state before allowing them to drop down to the regular cached LRU list.  This is
450    // to avoid thrashing of provider processes under low memory situations.
451    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
452
453    // How long we wait for a launched process to attach to the activity manager
454    // before we decide it's never going to come up for real, when the process was
455    // started with a wrapper for instrumentation (such as Valgrind) because it
456    // could take much longer than usual.
457    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
458
459    // How long to wait after going idle before forcing apps to GC.
460    static final int GC_TIMEOUT = 5*1000;
461
462    // The minimum amount of time between successive GC requests for a process.
463    static final int GC_MIN_INTERVAL = 60*1000;
464
465    // The minimum amount of time between successive PSS requests for a process.
466    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
467
468    // The minimum amount of time between successive PSS requests for a process
469    // when the request is due to the memory state being lowered.
470    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
471
472    // The rate at which we check for apps using excessive power -- 15 mins.
473    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
474
475    // The minimum sample duration we will allow before deciding we have
476    // enough data on wake locks to start killing things.
477    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
478
479    // The minimum sample duration we will allow before deciding we have
480    // enough data on CPU usage to start killing things.
481    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
482
483    // How long we allow a receiver to run before giving up on it.
484    static final int BROADCAST_FG_TIMEOUT = 10*1000;
485    static final int BROADCAST_BG_TIMEOUT = 60*1000;
486
487    // How long we wait until we timeout on key dispatching.
488    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
489
490    // How long we wait until we timeout on key dispatching during instrumentation.
491    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
492
493    // This is the amount of time an app needs to be running a foreground service before
494    // we will consider it to be doing interaction for usage stats.
495    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
496
497    // Maximum amount of time we will allow to elapse before re-reporting usage stats
498    // interaction with foreground processes.
499    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
500
501    // This is the amount of time we allow an app to settle after it goes into the background,
502    // before we start restricting what it can do.
503    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
504
505    // How long to wait in getAssistContextExtras for the activity and foreground services
506    // to respond with the result.
507    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
508
509    // How long top wait when going through the modern assist (which doesn't need to block
510    // on getting this result before starting to launch its UI).
511    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
512
513    // Maximum number of persisted Uri grants a package is allowed
514    static final int MAX_PERSISTED_URI_GRANTS = 128;
515
516    static final int MY_PID = Process.myPid();
517
518    static final String[] EMPTY_STRING_ARRAY = new String[0];
519
520    // How many bytes to write into the dropbox log before truncating
521    static final int DROPBOX_MAX_SIZE = 192 * 1024;
522    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
523    // as one line, but close enough for now.
524    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
525
526    // Access modes for handleIncomingUser.
527    static final int ALLOW_NON_FULL = 0;
528    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
529    static final int ALLOW_FULL_ONLY = 2;
530
531    // Necessary ApplicationInfo flags to mark an app as persistent
532    private static final int PERSISTENT_MASK =
533            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
534
535    // Intent sent when remote bugreport collection has been completed
536    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
537            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
538
539    // Used to indicate that a task is removed it should also be removed from recents.
540    private static final boolean REMOVE_FROM_RECENTS = true;
541    // Used to indicate that an app transition should be animated.
542    static final boolean ANIMATE = true;
543
544    // Determines whether to take full screen screenshots
545    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
546    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
547
548    /** All system services */
549    SystemServiceManager mSystemServiceManager;
550
551    private Installer mInstaller;
552
553    /** Run all ActivityStacks through this */
554    final ActivityStackSupervisor mStackSupervisor;
555    private final KeyguardController mKeyguardController;
556
557    final ActivityStarter mActivityStarter;
558
559    final TaskChangeNotificationController mTaskChangeNotificationController;
560
561    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
562
563    public IntentFirewall mIntentFirewall;
564
565    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
566    // default action automatically.  Important for devices without direct input
567    // devices.
568    private boolean mShowDialogs = true;
569    private boolean mInVrMode = false;
570
571    // Whether we should use SCHED_FIFO for UI and RenderThreads.
572    private boolean mUseFifoUiScheduling = false;
573
574    BroadcastQueue mFgBroadcastQueue;
575    BroadcastQueue mBgBroadcastQueue;
576    // Convenient for easy iteration over the queues. Foreground is first
577    // so that dispatch of foreground broadcasts gets precedence.
578    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
579
580    BroadcastStats mLastBroadcastStats;
581    BroadcastStats mCurBroadcastStats;
582
583    BroadcastQueue broadcastQueueForIntent(Intent intent) {
584        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
585        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
586                "Broadcast intent " + intent + " on "
587                + (isFg ? "foreground" : "background") + " queue");
588        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
589    }
590
591    /**
592     * The last resumed activity. This is identical to the current resumed activity most
593     * of the time but could be different when we're pausing one activity before we resume
594     * another activity.
595     */
596    private ActivityRecord mLastResumedActivity;
597
598    /**
599     * If non-null, we are tracking the time the user spends in the currently focused app.
600     */
601    private AppTimeTracker mCurAppTimeTracker;
602
603    /**
604     * List of intents that were used to start the most recent tasks.
605     */
606    final RecentTasks mRecentTasks;
607
608    /**
609     * For addAppTask: cached of the last activity component that was added.
610     */
611    ComponentName mLastAddedTaskComponent;
612
613    /**
614     * For addAppTask: cached of the last activity uid that was added.
615     */
616    int mLastAddedTaskUid;
617
618    /**
619     * For addAppTask: cached of the last ActivityInfo that was added.
620     */
621    ActivityInfo mLastAddedTaskActivity;
622
623    /**
624     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625     */
626    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628    /**
629     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630     */
631    String mDeviceOwnerName;
632
633    final UserController mUserController;
634
635    final AppErrors mAppErrors;
636
637    public boolean canShowErrorDialogs() {
638        return mShowDialogs && !mSleeping && !mShuttingDown
639                && !mKeyguardController.isKeyguardShowing();
640    }
641
642    private static final class PriorityState {
643        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
644        // the current thread is currently in. When it drops down to zero, we will no longer boost
645        // the thread's priority.
646        private int regionCounter = 0;
647
648        // The thread's previous priority before boosting.
649        private int prevPriority = Integer.MIN_VALUE;
650    }
651
652    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
653        @Override protected PriorityState initialValue() {
654            return new PriorityState();
655        }
656    };
657
658    static void boostPriorityForLockedSection() {
659        int tid = Process.myTid();
660        int prevPriority = Process.getThreadPriority(tid);
661        PriorityState state = sThreadPriorityState.get();
662        if (state.regionCounter == 0 && prevPriority > -2) {
663            state.prevPriority = prevPriority;
664            Process.setThreadPriority(tid, -2);
665        }
666        state.regionCounter++;
667    }
668
669    static void resetPriorityAfterLockedSection() {
670        PriorityState state = sThreadPriorityState.get();
671        state.regionCounter--;
672        if (state.regionCounter == 0 && state.prevPriority > -2) {
673            Process.setThreadPriority(Process.myTid(), state.prevPriority);
674        }
675    }
676
677    public class PendingAssistExtras extends Binder implements Runnable {
678        public final ActivityRecord activity;
679        public final Bundle extras;
680        public final Intent intent;
681        public final String hint;
682        public final IResultReceiver receiver;
683        public final int userHandle;
684        public boolean haveResult = false;
685        public Bundle result = null;
686        public AssistStructure structure = null;
687        public AssistContent content = null;
688        public Bundle receiverExtras;
689
690        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
691                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
692            activity = _activity;
693            extras = _extras;
694            intent = _intent;
695            hint = _hint;
696            receiver = _receiver;
697            receiverExtras = _receiverExtras;
698            userHandle = _userHandle;
699        }
700        @Override
701        public void run() {
702            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
703            synchronized (this) {
704                haveResult = true;
705                notifyAll();
706            }
707            pendingAssistExtrasTimedOut(this);
708        }
709    }
710
711    final ArrayList<PendingAssistExtras> mPendingAssistExtras
712            = new ArrayList<PendingAssistExtras>();
713
714    /**
715     * Process management.
716     */
717    final ProcessList mProcessList = new ProcessList();
718
719    /**
720     * All of the applications we currently have running organized by name.
721     * The keys are strings of the application package name (as
722     * returned by the package manager), and the keys are ApplicationRecord
723     * objects.
724     */
725    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
726
727    /**
728     * Tracking long-term execution of processes to look for abuse and other
729     * bad app behavior.
730     */
731    final ProcessStatsService mProcessStats;
732
733    /**
734     * The currently running isolated processes.
735     */
736    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
737
738    /**
739     * Counter for assigning isolated process uids, to avoid frequently reusing the
740     * same ones.
741     */
742    int mNextIsolatedProcessUid = 0;
743
744    /**
745     * The currently running heavy-weight process, if any.
746     */
747    ProcessRecord mHeavyWeightProcess = null;
748
749    /**
750     * All of the processes we currently have running organized by pid.
751     * The keys are the pid running the application.
752     *
753     * <p>NOTE: This object is protected by its own lock, NOT the global
754     * activity manager lock!
755     */
756    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
757
758    /**
759     * All of the processes that have been forced to be foreground.  The key
760     * is the pid of the caller who requested it (we hold a death
761     * link on it).
762     */
763    abstract class ForegroundToken implements IBinder.DeathRecipient {
764        int pid;
765        IBinder token;
766    }
767    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
768
769    /**
770     * List of records for processes that someone had tried to start before the
771     * system was ready.  We don't start them at that point, but ensure they
772     * are started by the time booting is complete.
773     */
774    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
775
776    /**
777     * List of persistent applications that are in the process
778     * of being started.
779     */
780    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
781
782    /**
783     * Processes that are being forcibly torn down.
784     */
785    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
786
787    /**
788     * List of running applications, sorted by recent usage.
789     * The first entry in the list is the least recently used.
790     */
791    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
792
793    /**
794     * Where in mLruProcesses that the processes hosting activities start.
795     */
796    int mLruProcessActivityStart = 0;
797
798    /**
799     * Where in mLruProcesses that the processes hosting services start.
800     * This is after (lower index) than mLruProcessesActivityStart.
801     */
802    int mLruProcessServiceStart = 0;
803
804    /**
805     * List of processes that should gc as soon as things are idle.
806     */
807    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
808
809    /**
810     * Processes we want to collect PSS data from.
811     */
812    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
813
814    private boolean mBinderTransactionTrackingEnabled = false;
815
816    /**
817     * Last time we requested PSS data of all processes.
818     */
819    long mLastFullPssTime = SystemClock.uptimeMillis();
820
821    /**
822     * If set, the next time we collect PSS data we should do a full collection
823     * with data from native processes and the kernel.
824     */
825    boolean mFullPssPending = false;
826
827    /**
828     * This is the process holding what we currently consider to be
829     * the "home" activity.
830     */
831    ProcessRecord mHomeProcess;
832
833    /**
834     * This is the process holding the activity the user last visited that
835     * is in a different process from the one they are currently in.
836     */
837    ProcessRecord mPreviousProcess;
838
839    /**
840     * The time at which the previous process was last visible.
841     */
842    long mPreviousProcessVisibleTime;
843
844    /**
845     * Track all uids that have actively running processes.
846     */
847    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
848
849    /**
850     * This is for verifying the UID report flow.
851     */
852    static final boolean VALIDATE_UID_STATES = true;
853    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
854
855    /**
856     * Packages that the user has asked to have run in screen size
857     * compatibility mode instead of filling the screen.
858     */
859    final CompatModePackages mCompatModePackages;
860
861    /**
862     * Set of IntentSenderRecord objects that are currently active.
863     */
864    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
865            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
866
867    /**
868     * Fingerprints (hashCode()) of stack traces that we've
869     * already logged DropBox entries for.  Guarded by itself.  If
870     * something (rogue user app) forces this over
871     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
872     */
873    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
874    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
875
876    /**
877     * Strict Mode background batched logging state.
878     *
879     * The string buffer is guarded by itself, and its lock is also
880     * used to determine if another batched write is already
881     * in-flight.
882     */
883    private final StringBuilder mStrictModeBuffer = new StringBuilder();
884
885    /**
886     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
887     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
888     */
889    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
890
891    /**
892     * Resolver for broadcast intents to registered receivers.
893     * Holds BroadcastFilter (subclass of IntentFilter).
894     */
895    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
896            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
897        @Override
898        protected boolean allowFilterResult(
899                BroadcastFilter filter, List<BroadcastFilter> dest) {
900            IBinder target = filter.receiverList.receiver.asBinder();
901            for (int i = dest.size() - 1; i >= 0; i--) {
902                if (dest.get(i).receiverList.receiver.asBinder() == target) {
903                    return false;
904                }
905            }
906            return true;
907        }
908
909        @Override
910        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
911            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
912                    || userId == filter.owningUserId) {
913                return super.newResult(filter, match, userId);
914            }
915            return null;
916        }
917
918        @Override
919        protected BroadcastFilter[] newArray(int size) {
920            return new BroadcastFilter[size];
921        }
922
923        @Override
924        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
925            return packageName.equals(filter.packageName);
926        }
927    };
928
929    /**
930     * State of all active sticky broadcasts per user.  Keys are the action of the
931     * sticky Intent, values are an ArrayList of all broadcasted intents with
932     * that action (which should usually be one).  The SparseArray is keyed
933     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
934     * for stickies that are sent to all users.
935     */
936    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
937            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
938
939    final ActiveServices mServices;
940
941    final static class Association {
942        final int mSourceUid;
943        final String mSourceProcess;
944        final int mTargetUid;
945        final ComponentName mTargetComponent;
946        final String mTargetProcess;
947
948        int mCount;
949        long mTime;
950
951        int mNesting;
952        long mStartTime;
953
954        // states of the source process when the bind occurred.
955        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
956        long mLastStateUptime;
957        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
958                - ActivityManager.MIN_PROCESS_STATE+1];
959
960        Association(int sourceUid, String sourceProcess, int targetUid,
961                ComponentName targetComponent, String targetProcess) {
962            mSourceUid = sourceUid;
963            mSourceProcess = sourceProcess;
964            mTargetUid = targetUid;
965            mTargetComponent = targetComponent;
966            mTargetProcess = targetProcess;
967        }
968    }
969
970    /**
971     * When service association tracking is enabled, this is all of the associations we
972     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
973     * -> association data.
974     */
975    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
976            mAssociations = new SparseArray<>();
977    boolean mTrackingAssociations;
978
979    /**
980     * Backup/restore process management
981     */
982    String mBackupAppName = null;
983    BackupRecord mBackupTarget = null;
984
985    final ProviderMap mProviderMap;
986
987    /**
988     * List of content providers who have clients waiting for them.  The
989     * application is currently being launched and the provider will be
990     * removed from this list once it is published.
991     */
992    final ArrayList<ContentProviderRecord> mLaunchingProviders
993            = new ArrayList<ContentProviderRecord>();
994
995    /**
996     * File storing persisted {@link #mGrantedUriPermissions}.
997     */
998    private final AtomicFile mGrantFile;
999
1000    /** XML constants used in {@link #mGrantFile} */
1001    private static final String TAG_URI_GRANTS = "uri-grants";
1002    private static final String TAG_URI_GRANT = "uri-grant";
1003    private static final String ATTR_USER_HANDLE = "userHandle";
1004    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1005    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1006    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1007    private static final String ATTR_TARGET_PKG = "targetPkg";
1008    private static final String ATTR_URI = "uri";
1009    private static final String ATTR_MODE_FLAGS = "modeFlags";
1010    private static final String ATTR_CREATED_TIME = "createdTime";
1011    private static final String ATTR_PREFIX = "prefix";
1012
1013    /**
1014     * Global set of specific {@link Uri} permissions that have been granted.
1015     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1016     * to {@link UriPermission#uri} to {@link UriPermission}.
1017     */
1018    @GuardedBy("this")
1019    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1020            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1021
1022    public static class GrantUri {
1023        public final int sourceUserId;
1024        public final Uri uri;
1025        public boolean prefix;
1026
1027        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1028            this.sourceUserId = sourceUserId;
1029            this.uri = uri;
1030            this.prefix = prefix;
1031        }
1032
1033        @Override
1034        public int hashCode() {
1035            int hashCode = 1;
1036            hashCode = 31 * hashCode + sourceUserId;
1037            hashCode = 31 * hashCode + uri.hashCode();
1038            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1039            return hashCode;
1040        }
1041
1042        @Override
1043        public boolean equals(Object o) {
1044            if (o instanceof GrantUri) {
1045                GrantUri other = (GrantUri) o;
1046                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1047                        && prefix == other.prefix;
1048            }
1049            return false;
1050        }
1051
1052        @Override
1053        public String toString() {
1054            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1055            if (prefix) result += " [prefix]";
1056            return result;
1057        }
1058
1059        public String toSafeString() {
1060            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1061            if (prefix) result += " [prefix]";
1062            return result;
1063        }
1064
1065        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1066            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1067                    ContentProvider.getUriWithoutUserId(uri), false);
1068        }
1069    }
1070
1071    CoreSettingsObserver mCoreSettingsObserver;
1072
1073    FontScaleSettingObserver mFontScaleSettingObserver;
1074
1075    private final class FontScaleSettingObserver extends ContentObserver {
1076        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1077
1078        public FontScaleSettingObserver() {
1079            super(mHandler);
1080            ContentResolver resolver = mContext.getContentResolver();
1081            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1082        }
1083
1084        @Override
1085        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1086            if (mFontScaleUri.equals(uri)) {
1087                updateFontScaleIfNeeded(userId);
1088            }
1089        }
1090    }
1091
1092    /**
1093     * Thread-local storage used to carry caller permissions over through
1094     * indirect content-provider access.
1095     */
1096    private class Identity {
1097        public final IBinder token;
1098        public final int pid;
1099        public final int uid;
1100
1101        Identity(IBinder _token, int _pid, int _uid) {
1102            token = _token;
1103            pid = _pid;
1104            uid = _uid;
1105        }
1106    }
1107
1108    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1109
1110    /**
1111     * All information we have collected about the runtime performance of
1112     * any user id that can impact battery performance.
1113     */
1114    final BatteryStatsService mBatteryStatsService;
1115
1116    /**
1117     * Information about component usage
1118     */
1119    UsageStatsManagerInternal mUsageStatsService;
1120
1121    /**
1122     * Access to DeviceIdleController service.
1123     */
1124    DeviceIdleController.LocalService mLocalDeviceIdleController;
1125
1126    /**
1127     * Information about and control over application operations
1128     */
1129    final AppOpsService mAppOpsService;
1130
1131    /** Current sequencing integer of the configuration, for skipping old configurations. */
1132    private int mConfigurationSeq;
1133
1134    /**
1135     * Temp object used when global and/or display override configuration is updated. It is also
1136     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1137     * anyone...
1138     */
1139    private Configuration mTempConfig = new Configuration();
1140
1141    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1142            new UpdateConfigurationResult();
1143    private static final class UpdateConfigurationResult {
1144        // Configuration changes that were updated.
1145        int changes;
1146        // If the activity was relaunched to match the new configuration.
1147        boolean activityRelaunched;
1148
1149        void reset() {
1150            changes = 0;
1151            activityRelaunched = false;
1152        }
1153    }
1154
1155    boolean mSuppressResizeConfigChanges;
1156
1157    /**
1158     * Hardware-reported OpenGLES version.
1159     */
1160    final int GL_ES_VERSION;
1161
1162    /**
1163     * List of initialization arguments to pass to all processes when binding applications to them.
1164     * For example, references to the commonly used services.
1165     */
1166    HashMap<String, IBinder> mAppBindArgs;
1167    HashMap<String, IBinder> mIsolatedAppBindArgs;
1168
1169    /**
1170     * Temporary to avoid allocations.  Protected by main lock.
1171     */
1172    final StringBuilder mStringBuilder = new StringBuilder(256);
1173
1174    /**
1175     * Used to control how we initialize the service.
1176     */
1177    ComponentName mTopComponent;
1178    String mTopAction = Intent.ACTION_MAIN;
1179    String mTopData;
1180
1181    volatile boolean mProcessesReady = false;
1182    volatile boolean mSystemReady = false;
1183    volatile boolean mOnBattery = false;
1184    volatile int mFactoryTest;
1185
1186    @GuardedBy("this") boolean mBooting = false;
1187    @GuardedBy("this") boolean mCallFinishBooting = false;
1188    @GuardedBy("this") boolean mBootAnimationComplete = false;
1189    @GuardedBy("this") boolean mLaunchWarningShown = false;
1190    @GuardedBy("this") boolean mCheckedForSetup = false;
1191
1192    Context mContext;
1193
1194    /**
1195     * The time at which we will allow normal application switches again,
1196     * after a call to {@link #stopAppSwitches()}.
1197     */
1198    long mAppSwitchesAllowedTime;
1199
1200    /**
1201     * This is set to true after the first switch after mAppSwitchesAllowedTime
1202     * is set; any switches after that will clear the time.
1203     */
1204    boolean mDidAppSwitch;
1205
1206    /**
1207     * Last time (in realtime) at which we checked for power usage.
1208     */
1209    long mLastPowerCheckRealtime;
1210
1211    /**
1212     * Last time (in uptime) at which we checked for power usage.
1213     */
1214    long mLastPowerCheckUptime;
1215
1216    /**
1217     * Set while we are wanting to sleep, to prevent any
1218     * activities from being started/resumed.
1219     */
1220    private boolean mSleeping = false;
1221
1222    /**
1223     * The process state used for processes that are running the top activities.
1224     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1225     */
1226    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1227
1228    /**
1229     * Set while we are running a voice interaction.  This overrides
1230     * sleeping while it is active.
1231     */
1232    private IVoiceInteractionSession mRunningVoice;
1233
1234    /**
1235     * For some direct access we need to power manager.
1236     */
1237    PowerManagerInternal mLocalPowerManager;
1238
1239    /**
1240     * We want to hold a wake lock while running a voice interaction session, since
1241     * this may happen with the screen off and we need to keep the CPU running to
1242     * be able to continue to interact with the user.
1243     */
1244    PowerManager.WakeLock mVoiceWakeLock;
1245
1246    /**
1247     * State of external calls telling us if the device is awake or asleep.
1248     */
1249    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1250
1251    /**
1252     * A list of tokens that cause the top activity to be put to sleep.
1253     * They are used by components that may hide and block interaction with underlying
1254     * activities.
1255     */
1256    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1257
1258    /**
1259     * Set if we are shutting down the system, similar to sleeping.
1260     */
1261    boolean mShuttingDown = false;
1262
1263    /**
1264     * Current sequence id for oom_adj computation traversal.
1265     */
1266    int mAdjSeq = 0;
1267
1268    /**
1269     * Current sequence id for process LRU updating.
1270     */
1271    int mLruSeq = 0;
1272
1273    /**
1274     * Keep track of the non-cached/empty process we last found, to help
1275     * determine how to distribute cached/empty processes next time.
1276     */
1277    int mNumNonCachedProcs = 0;
1278
1279    /**
1280     * Keep track of the number of cached hidden procs, to balance oom adj
1281     * distribution between those and empty procs.
1282     */
1283    int mNumCachedHiddenProcs = 0;
1284
1285    /**
1286     * Keep track of the number of service processes we last found, to
1287     * determine on the next iteration which should be B services.
1288     */
1289    int mNumServiceProcs = 0;
1290    int mNewNumAServiceProcs = 0;
1291    int mNewNumServiceProcs = 0;
1292
1293    /**
1294     * Allow the current computed overall memory level of the system to go down?
1295     * This is set to false when we are killing processes for reasons other than
1296     * memory management, so that the now smaller process list will not be taken as
1297     * an indication that memory is tighter.
1298     */
1299    boolean mAllowLowerMemLevel = false;
1300
1301    /**
1302     * The last computed memory level, for holding when we are in a state that
1303     * processes are going away for other reasons.
1304     */
1305    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1306
1307    /**
1308     * The last total number of process we have, to determine if changes actually look
1309     * like a shrinking number of process due to lower RAM.
1310     */
1311    int mLastNumProcesses;
1312
1313    /**
1314     * The uptime of the last time we performed idle maintenance.
1315     */
1316    long mLastIdleTime = SystemClock.uptimeMillis();
1317
1318    /**
1319     * Total time spent with RAM that has been added in the past since the last idle time.
1320     */
1321    long mLowRamTimeSinceLastIdle = 0;
1322
1323    /**
1324     * If RAM is currently low, when that horrible situation started.
1325     */
1326    long mLowRamStartTime = 0;
1327
1328    /**
1329     * For reporting to battery stats the current top application.
1330     */
1331    private String mCurResumedPackage = null;
1332    private int mCurResumedUid = -1;
1333
1334    /**
1335     * For reporting to battery stats the apps currently running foreground
1336     * service.  The ProcessMap is package/uid tuples; each of these contain
1337     * an array of the currently foreground processes.
1338     */
1339    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1340            = new ProcessMap<ArrayList<ProcessRecord>>();
1341
1342    /**
1343     * This is set if we had to do a delayed dexopt of an app before launching
1344     * it, to increase the ANR timeouts in that case.
1345     */
1346    boolean mDidDexOpt;
1347
1348    /**
1349     * Set if the systemServer made a call to enterSafeMode.
1350     */
1351    boolean mSafeMode;
1352
1353    /**
1354     * If true, we are running under a test environment so will sample PSS from processes
1355     * much more rapidly to try to collect better data when the tests are rapidly
1356     * running through apps.
1357     */
1358    boolean mTestPssMode = false;
1359
1360    String mDebugApp = null;
1361    boolean mWaitForDebugger = false;
1362    boolean mDebugTransient = false;
1363    String mOrigDebugApp = null;
1364    boolean mOrigWaitForDebugger = false;
1365    boolean mAlwaysFinishActivities = false;
1366    boolean mLenientBackgroundCheck = false;
1367    boolean mForceResizableActivities;
1368    boolean mSupportsMultiWindow;
1369    boolean mSupportsFreeformWindowManagement;
1370    boolean mSupportsPictureInPicture;
1371    boolean mSupportsLeanbackOnly;
1372    IActivityController mController = null;
1373    boolean mControllerIsAMonkey = false;
1374    String mProfileApp = null;
1375    ProcessRecord mProfileProc = null;
1376    String mProfileFile;
1377    ParcelFileDescriptor mProfileFd;
1378    int mSamplingInterval = 0;
1379    boolean mAutoStopProfiler = false;
1380    int mProfileType = 0;
1381    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1382    String mMemWatchDumpProcName;
1383    String mMemWatchDumpFile;
1384    int mMemWatchDumpPid;
1385    int mMemWatchDumpUid;
1386    String mTrackAllocationApp = null;
1387    String mNativeDebuggingApp = null;
1388
1389    final long[] mTmpLong = new long[2];
1390
1391    static final class ProcessChangeItem {
1392        static final int CHANGE_ACTIVITIES = 1<<0;
1393        static final int CHANGE_PROCESS_STATE = 1<<1;
1394        int changes;
1395        int uid;
1396        int pid;
1397        int processState;
1398        boolean foregroundActivities;
1399    }
1400
1401    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1402    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1403
1404    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1405    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1406
1407    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1408    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1409
1410    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1411    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1412
1413    /**
1414     * Runtime CPU use collection thread.  This object's lock is used to
1415     * perform synchronization with the thread (notifying it to run).
1416     */
1417    final Thread mProcessCpuThread;
1418
1419    /**
1420     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1421     * Must acquire this object's lock when accessing it.
1422     * NOTE: this lock will be held while doing long operations (trawling
1423     * through all processes in /proc), so it should never be acquired by
1424     * any critical paths such as when holding the main activity manager lock.
1425     */
1426    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1427            MONITOR_THREAD_CPU_USAGE);
1428    final AtomicLong mLastCpuTime = new AtomicLong(0);
1429    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1430
1431    long mLastWriteTime = 0;
1432
1433    /**
1434     * Used to retain an update lock when the foreground activity is in
1435     * immersive mode.
1436     */
1437    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1438
1439    /**
1440     * Set to true after the system has finished booting.
1441     */
1442    boolean mBooted = false;
1443
1444    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1445    int mProcessLimitOverride = -1;
1446
1447    WindowManagerService mWindowManager;
1448    final ActivityThread mSystemThread;
1449
1450    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1451        final ProcessRecord mApp;
1452        final int mPid;
1453        final IApplicationThread mAppThread;
1454
1455        AppDeathRecipient(ProcessRecord app, int pid,
1456                IApplicationThread thread) {
1457            if (DEBUG_ALL) Slog.v(
1458                TAG, "New death recipient " + this
1459                + " for thread " + thread.asBinder());
1460            mApp = app;
1461            mPid = pid;
1462            mAppThread = thread;
1463        }
1464
1465        @Override
1466        public void binderDied() {
1467            if (DEBUG_ALL) Slog.v(
1468                TAG, "Death received in " + this
1469                + " for thread " + mAppThread.asBinder());
1470            synchronized(ActivityManagerService.this) {
1471                appDiedLocked(mApp, mPid, mAppThread, true);
1472            }
1473        }
1474    }
1475
1476    static final int SHOW_ERROR_UI_MSG = 1;
1477    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1478    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1479    static final int UPDATE_CONFIGURATION_MSG = 4;
1480    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1481    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1482    static final int SERVICE_TIMEOUT_MSG = 12;
1483    static final int UPDATE_TIME_ZONE = 13;
1484    static final int SHOW_UID_ERROR_UI_MSG = 14;
1485    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1486    static final int PROC_START_TIMEOUT_MSG = 20;
1487    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1488    static final int KILL_APPLICATION_MSG = 22;
1489    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1490    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1491    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1492    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1493    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1494    static final int CLEAR_DNS_CACHE_MSG = 28;
1495    static final int UPDATE_HTTP_PROXY_MSG = 29;
1496    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1497    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1498    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1499    static final int REPORT_MEM_USAGE_MSG = 33;
1500    static final int REPORT_USER_SWITCH_MSG = 34;
1501    static final int CONTINUE_USER_SWITCH_MSG = 35;
1502    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1503    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1504    static final int PERSIST_URI_GRANTS_MSG = 38;
1505    static final int REQUEST_ALL_PSS_MSG = 39;
1506    static final int START_PROFILES_MSG = 40;
1507    static final int UPDATE_TIME = 41;
1508    static final int SYSTEM_USER_START_MSG = 42;
1509    static final int SYSTEM_USER_CURRENT_MSG = 43;
1510    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1511    static final int FINISH_BOOTING_MSG = 45;
1512    static final int START_USER_SWITCH_UI_MSG = 46;
1513    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1514    static final int DISMISS_DIALOG_UI_MSG = 48;
1515    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1516    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1517    static final int DELETE_DUMPHEAP_MSG = 51;
1518    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1519    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1520    static final int REPORT_TIME_TRACKER_MSG = 54;
1521    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1522    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1523    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1524    static final int IDLE_UIDS_MSG = 58;
1525    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1526    static final int LOG_STACK_STATE = 60;
1527    static final int VR_MODE_CHANGE_MSG = 61;
1528    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 62;
1529    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 63;
1530    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 64;
1531    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 65;
1532    static final int START_USER_SWITCH_FG_MSG = 712;
1533
1534    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1535    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1536    static final int FIRST_COMPAT_MODE_MSG = 300;
1537    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1538
1539    static ServiceThread sKillThread = null;
1540    static KillHandler sKillHandler = null;
1541
1542    CompatModeDialog mCompatModeDialog;
1543    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1544    long mLastMemUsageReportTime = 0;
1545
1546    /**
1547     * Flag whether the current user is a "monkey", i.e. whether
1548     * the UI is driven by a UI automation tool.
1549     */
1550    private boolean mUserIsMonkey;
1551
1552    /** Flag whether the device has a Recents UI */
1553    boolean mHasRecents;
1554
1555    /** The dimensions of the thumbnails in the Recents UI. */
1556    int mThumbnailWidth;
1557    int mThumbnailHeight;
1558    float mFullscreenThumbnailScale;
1559
1560    final ServiceThread mHandlerThread;
1561    final MainHandler mHandler;
1562    final UiHandler mUiHandler;
1563
1564    PackageManagerInternal mPackageManagerInt;
1565
1566    // VoiceInteraction session ID that changes for each new request except when
1567    // being called for multiwindow assist in a single session.
1568    private int mViSessionId = 1000;
1569
1570    final boolean mPermissionReviewRequired;
1571
1572    /**
1573     * Current global configuration information. Contains general settings for the entire system,
1574     * also corresponds to the merged configuration of the default display.
1575     */
1576    Configuration getGlobalConfiguration() {
1577        return mStackSupervisor.getConfiguration();
1578    }
1579
1580    final class KillHandler extends Handler {
1581        static final int KILL_PROCESS_GROUP_MSG = 4000;
1582
1583        public KillHandler(Looper looper) {
1584            super(looper, null, true);
1585        }
1586
1587        @Override
1588        public void handleMessage(Message msg) {
1589            switch (msg.what) {
1590                case KILL_PROCESS_GROUP_MSG:
1591                {
1592                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1593                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1594                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1595                }
1596                break;
1597
1598                default:
1599                    super.handleMessage(msg);
1600            }
1601        }
1602    }
1603
1604    final class UiHandler extends Handler {
1605        public UiHandler() {
1606            super(com.android.server.UiThread.get().getLooper(), null, true);
1607        }
1608
1609        @Override
1610        public void handleMessage(Message msg) {
1611            switch (msg.what) {
1612            case SHOW_ERROR_UI_MSG: {
1613                mAppErrors.handleShowAppErrorUi(msg);
1614                ensureBootCompleted();
1615            } break;
1616            case SHOW_NOT_RESPONDING_UI_MSG: {
1617                mAppErrors.handleShowAnrUi(msg);
1618                ensureBootCompleted();
1619            } break;
1620            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1621                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1622                synchronized (ActivityManagerService.this) {
1623                    ProcessRecord proc = (ProcessRecord) data.get("app");
1624                    if (proc == null) {
1625                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1626                        break;
1627                    }
1628                    if (proc.crashDialog != null) {
1629                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1630                        return;
1631                    }
1632                    AppErrorResult res = (AppErrorResult) data.get("result");
1633                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1634                        Dialog d = new StrictModeViolationDialog(mContext,
1635                                ActivityManagerService.this, res, proc);
1636                        d.show();
1637                        proc.crashDialog = d;
1638                    } else {
1639                        // The device is asleep, so just pretend that the user
1640                        // saw a crash dialog and hit "force quit".
1641                        res.set(0);
1642                    }
1643                }
1644                ensureBootCompleted();
1645            } break;
1646            case SHOW_FACTORY_ERROR_UI_MSG: {
1647                Dialog d = new FactoryErrorDialog(
1648                    mContext, msg.getData().getCharSequence("msg"));
1649                d.show();
1650                ensureBootCompleted();
1651            } break;
1652            case WAIT_FOR_DEBUGGER_UI_MSG: {
1653                synchronized (ActivityManagerService.this) {
1654                    ProcessRecord app = (ProcessRecord)msg.obj;
1655                    if (msg.arg1 != 0) {
1656                        if (!app.waitedForDebugger) {
1657                            Dialog d = new AppWaitingForDebuggerDialog(
1658                                    ActivityManagerService.this,
1659                                    mContext, app);
1660                            app.waitDialog = d;
1661                            app.waitedForDebugger = true;
1662                            d.show();
1663                        }
1664                    } else {
1665                        if (app.waitDialog != null) {
1666                            app.waitDialog.dismiss();
1667                            app.waitDialog = null;
1668                        }
1669                    }
1670                }
1671            } break;
1672            case SHOW_UID_ERROR_UI_MSG: {
1673                if (mShowDialogs) {
1674                    AlertDialog d = new BaseErrorDialog(mContext);
1675                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1676                    d.setCancelable(false);
1677                    d.setTitle(mContext.getText(R.string.android_system_label));
1678                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1679                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1680                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1681                    d.show();
1682                }
1683            } break;
1684            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1685                if (mShowDialogs) {
1686                    AlertDialog d = new BaseErrorDialog(mContext);
1687                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1688                    d.setCancelable(false);
1689                    d.setTitle(mContext.getText(R.string.android_system_label));
1690                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1691                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1692                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1693                    d.show();
1694                }
1695            } break;
1696            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    ActivityRecord ar = (ActivityRecord) msg.obj;
1699                    if (mCompatModeDialog != null) {
1700                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1701                                ar.info.applicationInfo.packageName)) {
1702                            return;
1703                        }
1704                        mCompatModeDialog.dismiss();
1705                        mCompatModeDialog = null;
1706                    }
1707                    if (ar != null && false) {
1708                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1709                                ar.packageName)) {
1710                            int mode = mCompatModePackages.computeCompatModeLocked(
1711                                    ar.info.applicationInfo);
1712                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1713                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1714                                mCompatModeDialog = new CompatModeDialog(
1715                                        ActivityManagerService.this, mContext,
1716                                        ar.info.applicationInfo);
1717                                mCompatModeDialog.show();
1718                            }
1719                        }
1720                    }
1721                }
1722                break;
1723            }
1724            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1727                    if (mUnsupportedDisplaySizeDialog != null) {
1728                        mUnsupportedDisplaySizeDialog.dismiss();
1729                        mUnsupportedDisplaySizeDialog = null;
1730                    }
1731                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1732                            ar.packageName)) {
1733                        // TODO(multi-display): Show dialog on appropriate display.
1734                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1735                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1736                        mUnsupportedDisplaySizeDialog.show();
1737                    }
1738                }
1739                break;
1740            }
1741            case START_USER_SWITCH_UI_MSG: {
1742                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1743                break;
1744            }
1745            case DISMISS_DIALOG_UI_MSG: {
1746                final Dialog d = (Dialog) msg.obj;
1747                d.dismiss();
1748                break;
1749            }
1750            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1751                dispatchProcessesChanged();
1752                break;
1753            }
1754            case DISPATCH_PROCESS_DIED_UI_MSG: {
1755                final int pid = msg.arg1;
1756                final int uid = msg.arg2;
1757                dispatchProcessDied(pid, uid);
1758                break;
1759            }
1760            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1761                dispatchUidsChanged();
1762            } break;
1763            }
1764        }
1765    }
1766
1767    final class MainHandler extends Handler {
1768        public MainHandler(Looper looper) {
1769            super(looper, null, true);
1770        }
1771
1772        @Override
1773        public void handleMessage(Message msg) {
1774            switch (msg.what) {
1775            case UPDATE_CONFIGURATION_MSG: {
1776                final ContentResolver resolver = mContext.getContentResolver();
1777                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1778                        msg.arg1);
1779            } break;
1780            case GC_BACKGROUND_PROCESSES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    performAppGcsIfAppropriateLocked();
1783                }
1784            } break;
1785            case SERVICE_TIMEOUT_MSG: {
1786                if (mDidDexOpt) {
1787                    mDidDexOpt = false;
1788                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1789                    nmsg.obj = msg.obj;
1790                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1791                    return;
1792                }
1793                mServices.serviceTimeout((ProcessRecord)msg.obj);
1794            } break;
1795            case UPDATE_TIME_ZONE: {
1796                synchronized (ActivityManagerService.this) {
1797                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1798                        ProcessRecord r = mLruProcesses.get(i);
1799                        if (r.thread != null) {
1800                            try {
1801                                r.thread.updateTimeZone();
1802                            } catch (RemoteException ex) {
1803                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1804                            }
1805                        }
1806                    }
1807                }
1808            } break;
1809            case CLEAR_DNS_CACHE_MSG: {
1810                synchronized (ActivityManagerService.this) {
1811                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1812                        ProcessRecord r = mLruProcesses.get(i);
1813                        if (r.thread != null) {
1814                            try {
1815                                r.thread.clearDnsCache();
1816                            } catch (RemoteException ex) {
1817                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1818                            }
1819                        }
1820                    }
1821                }
1822            } break;
1823            case UPDATE_HTTP_PROXY_MSG: {
1824                ProxyInfo proxy = (ProxyInfo)msg.obj;
1825                String host = "";
1826                String port = "";
1827                String exclList = "";
1828                Uri pacFileUrl = Uri.EMPTY;
1829                if (proxy != null) {
1830                    host = proxy.getHost();
1831                    port = Integer.toString(proxy.getPort());
1832                    exclList = proxy.getExclusionListAsString();
1833                    pacFileUrl = proxy.getPacFileUrl();
1834                }
1835                synchronized (ActivityManagerService.this) {
1836                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1837                        ProcessRecord r = mLruProcesses.get(i);
1838                        if (r.thread != null) {
1839                            try {
1840                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1841                            } catch (RemoteException ex) {
1842                                Slog.w(TAG, "Failed to update http proxy for: " +
1843                                        r.info.processName);
1844                            }
1845                        }
1846                    }
1847                }
1848            } break;
1849            case PROC_START_TIMEOUT_MSG: {
1850                if (mDidDexOpt) {
1851                    mDidDexOpt = false;
1852                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1853                    nmsg.obj = msg.obj;
1854                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1855                    return;
1856                }
1857                ProcessRecord app = (ProcessRecord)msg.obj;
1858                synchronized (ActivityManagerService.this) {
1859                    processStartTimedOutLocked(app);
1860                }
1861            } break;
1862            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1863                ProcessRecord app = (ProcessRecord)msg.obj;
1864                synchronized (ActivityManagerService.this) {
1865                    processContentProviderPublishTimedOutLocked(app);
1866                }
1867            } break;
1868            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1871                }
1872            } break;
1873            case KILL_APPLICATION_MSG: {
1874                synchronized (ActivityManagerService.this) {
1875                    final int appId = msg.arg1;
1876                    final int userId = msg.arg2;
1877                    Bundle bundle = (Bundle)msg.obj;
1878                    String pkg = bundle.getString("pkg");
1879                    String reason = bundle.getString("reason");
1880                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1881                            false, userId, reason);
1882                }
1883            } break;
1884            case FINALIZE_PENDING_INTENT_MSG: {
1885                ((PendingIntentRecord)msg.obj).completeFinalize();
1886            } break;
1887            case POST_HEAVY_NOTIFICATION_MSG: {
1888                INotificationManager inm = NotificationManager.getService();
1889                if (inm == null) {
1890                    return;
1891                }
1892
1893                ActivityRecord root = (ActivityRecord)msg.obj;
1894                ProcessRecord process = root.app;
1895                if (process == null) {
1896                    return;
1897                }
1898
1899                try {
1900                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1901                    String text = mContext.getString(R.string.heavy_weight_notification,
1902                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1903                    Notification notification = new Notification.Builder(context)
1904                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1905                            .setWhen(0)
1906                            .setOngoing(true)
1907                            .setTicker(text)
1908                            .setColor(mContext.getColor(
1909                                    com.android.internal.R.color.system_notification_accent_color))
1910                            .setContentTitle(text)
1911                            .setContentText(
1912                                    mContext.getText(R.string.heavy_weight_notification_detail))
1913                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1914                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1915                                    new UserHandle(root.userId)))
1916                            .build();
1917                    try {
1918                        int[] outId = new int[1];
1919                        inm.enqueueNotificationWithTag("android", "android", null,
1920                                R.string.heavy_weight_notification,
1921                                notification, outId, root.userId);
1922                    } catch (RuntimeException e) {
1923                        Slog.w(ActivityManagerService.TAG,
1924                                "Error showing notification for heavy-weight app", e);
1925                    } catch (RemoteException e) {
1926                    }
1927                } catch (NameNotFoundException e) {
1928                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1929                }
1930            } break;
1931            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1932                INotificationManager inm = NotificationManager.getService();
1933                if (inm == null) {
1934                    return;
1935                }
1936                try {
1937                    inm.cancelNotificationWithTag("android", null,
1938                            R.string.heavy_weight_notification,  msg.arg1);
1939                } catch (RuntimeException e) {
1940                    Slog.w(ActivityManagerService.TAG,
1941                            "Error canceling notification for service", e);
1942                } catch (RemoteException e) {
1943                }
1944            } break;
1945            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1946                synchronized (ActivityManagerService.this) {
1947                    checkExcessivePowerUsageLocked(true);
1948                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1949                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1950                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1951                }
1952            } break;
1953            case REPORT_MEM_USAGE_MSG: {
1954                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1955                Thread thread = new Thread() {
1956                    @Override public void run() {
1957                        reportMemUsage(memInfos);
1958                    }
1959                };
1960                thread.start();
1961                break;
1962            }
1963            case START_USER_SWITCH_FG_MSG: {
1964                mUserController.startUserInForeground(msg.arg1);
1965                break;
1966            }
1967            case REPORT_USER_SWITCH_MSG: {
1968                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1969                break;
1970            }
1971            case CONTINUE_USER_SWITCH_MSG: {
1972                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1973                break;
1974            }
1975            case USER_SWITCH_TIMEOUT_MSG: {
1976                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1977                break;
1978            }
1979            case IMMERSIVE_MODE_LOCK_MSG: {
1980                final boolean nextState = (msg.arg1 != 0);
1981                if (mUpdateLock.isHeld() != nextState) {
1982                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1983                            "Applying new update lock state '" + nextState
1984                            + "' for " + (ActivityRecord)msg.obj);
1985                    if (nextState) {
1986                        mUpdateLock.acquire();
1987                    } else {
1988                        mUpdateLock.release();
1989                    }
1990                }
1991                break;
1992            }
1993            case PERSIST_URI_GRANTS_MSG: {
1994                writeGrantedUriPermissions();
1995                break;
1996            }
1997            case REQUEST_ALL_PSS_MSG: {
1998                synchronized (ActivityManagerService.this) {
1999                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2000                }
2001                break;
2002            }
2003            case START_PROFILES_MSG: {
2004                synchronized (ActivityManagerService.this) {
2005                    mUserController.startProfilesLocked();
2006                }
2007                break;
2008            }
2009            case UPDATE_TIME: {
2010                synchronized (ActivityManagerService.this) {
2011                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2012                        ProcessRecord r = mLruProcesses.get(i);
2013                        if (r.thread != null) {
2014                            try {
2015                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2016                            } catch (RemoteException ex) {
2017                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2018                            }
2019                        }
2020                    }
2021                }
2022                break;
2023            }
2024            case SYSTEM_USER_START_MSG: {
2025                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2026                        Integer.toString(msg.arg1), msg.arg1);
2027                mSystemServiceManager.startUser(msg.arg1);
2028                break;
2029            }
2030            case SYSTEM_USER_UNLOCK_MSG: {
2031                final int userId = msg.arg1;
2032                mSystemServiceManager.unlockUser(userId);
2033                synchronized (ActivityManagerService.this) {
2034                    mRecentTasks.loadUserRecentsLocked(userId);
2035                }
2036                if (userId == UserHandle.USER_SYSTEM) {
2037                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2038                }
2039                installEncryptionUnawareProviders(userId);
2040                mUserController.finishUserUnlocked((UserState) msg.obj);
2041                break;
2042            }
2043            case SYSTEM_USER_CURRENT_MSG: {
2044                mBatteryStatsService.noteEvent(
2045                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2046                        Integer.toString(msg.arg2), msg.arg2);
2047                mBatteryStatsService.noteEvent(
2048                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2049                        Integer.toString(msg.arg1), msg.arg1);
2050                mSystemServiceManager.switchUser(msg.arg1);
2051                break;
2052            }
2053            case ENTER_ANIMATION_COMPLETE_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2056                    if (r != null && r.app != null && r.app.thread != null) {
2057                        try {
2058                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2059                        } catch (RemoteException e) {
2060                        }
2061                    }
2062                }
2063                break;
2064            }
2065            case FINISH_BOOTING_MSG: {
2066                if (msg.arg1 != 0) {
2067                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2068                    finishBooting();
2069                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2070                }
2071                if (msg.arg2 != 0) {
2072                    enableScreenAfterBoot();
2073                }
2074                break;
2075            }
2076            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2077                try {
2078                    Locale l = (Locale) msg.obj;
2079                    IBinder service = ServiceManager.getService("mount");
2080                    IMountService mountService = IMountService.Stub.asInterface(service);
2081                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2082                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2083                } catch (RemoteException e) {
2084                    Log.e(TAG, "Error storing locale for decryption UI", e);
2085                }
2086                break;
2087            }
2088            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2089                final int uid = msg.arg1;
2090                final byte[] firstPacket = (byte[]) msg.obj;
2091
2092                synchronized (mPidsSelfLocked) {
2093                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2094                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2095                        if (p.uid == uid) {
2096                            try {
2097                                p.thread.notifyCleartextNetwork(firstPacket);
2098                            } catch (RemoteException ignored) {
2099                            }
2100                        }
2101                    }
2102                }
2103                break;
2104            }
2105            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2106                final String procName;
2107                final int uid;
2108                final long memLimit;
2109                final String reportPackage;
2110                synchronized (ActivityManagerService.this) {
2111                    procName = mMemWatchDumpProcName;
2112                    uid = mMemWatchDumpUid;
2113                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2114                    if (val == null) {
2115                        val = mMemWatchProcesses.get(procName, 0);
2116                    }
2117                    if (val != null) {
2118                        memLimit = val.first;
2119                        reportPackage = val.second;
2120                    } else {
2121                        memLimit = 0;
2122                        reportPackage = null;
2123                    }
2124                }
2125                if (procName == null) {
2126                    return;
2127                }
2128
2129                if (DEBUG_PSS) Slog.d(TAG_PSS,
2130                        "Showing dump heap notification from " + procName + "/" + uid);
2131
2132                INotificationManager inm = NotificationManager.getService();
2133                if (inm == null) {
2134                    return;
2135                }
2136
2137                String text = mContext.getString(R.string.dump_heap_notification, procName);
2138
2139
2140                Intent deleteIntent = new Intent();
2141                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2142                Intent intent = new Intent();
2143                intent.setClassName("android", DumpHeapActivity.class.getName());
2144                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2145                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2146                if (reportPackage != null) {
2147                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2148                }
2149                int userId = UserHandle.getUserId(uid);
2150                Notification notification = new Notification.Builder(mContext)
2151                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2152                        .setWhen(0)
2153                        .setOngoing(true)
2154                        .setAutoCancel(true)
2155                        .setTicker(text)
2156                        .setColor(mContext.getColor(
2157                                com.android.internal.R.color.system_notification_accent_color))
2158                        .setContentTitle(text)
2159                        .setContentText(
2160                                mContext.getText(R.string.dump_heap_notification_detail))
2161                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2162                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2163                                new UserHandle(userId)))
2164                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2165                                deleteIntent, 0, UserHandle.SYSTEM))
2166                        .build();
2167
2168                try {
2169                    int[] outId = new int[1];
2170                    inm.enqueueNotificationWithTag("android", "android", null,
2171                            R.string.dump_heap_notification,
2172                            notification, outId, userId);
2173                } catch (RuntimeException e) {
2174                    Slog.w(ActivityManagerService.TAG,
2175                            "Error showing notification for dump heap", e);
2176                } catch (RemoteException e) {
2177                }
2178            } break;
2179            case DELETE_DUMPHEAP_MSG: {
2180                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2181                        DumpHeapActivity.JAVA_URI,
2182                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2183                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2184                        UserHandle.myUserId());
2185                synchronized (ActivityManagerService.this) {
2186                    mMemWatchDumpFile = null;
2187                    mMemWatchDumpProcName = null;
2188                    mMemWatchDumpPid = -1;
2189                    mMemWatchDumpUid = -1;
2190                }
2191            } break;
2192            case FOREGROUND_PROFILE_CHANGED_MSG: {
2193                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2194            } break;
2195            case REPORT_TIME_TRACKER_MSG: {
2196                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2197                tracker.deliverResult(mContext);
2198            } break;
2199            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2200                mUserController.dispatchUserSwitchComplete(msg.arg1);
2201            } break;
2202            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2203                mUserController.dispatchLockedBootComplete(msg.arg1);
2204            } break;
2205            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2206                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2207                try {
2208                    connection.shutdown();
2209                } catch (RemoteException e) {
2210                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2211                }
2212                // Only a UiAutomation can set this flag and now that
2213                // it is finished we make sure it is reset to its default.
2214                mUserIsMonkey = false;
2215            } break;
2216            case IDLE_UIDS_MSG: {
2217                idleUids();
2218            } break;
2219            case VR_MODE_CHANGE_MSG: {
2220                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2221                if (vrService == null) {
2222                    break;
2223                }
2224                final ActivityRecord r = (ActivityRecord) msg.obj;
2225                boolean vrMode;
2226                ComponentName requestedPackage;
2227                ComponentName callingPackage;
2228                int userId;
2229                synchronized (ActivityManagerService.this) {
2230                    vrMode = r.requestedVrComponent != null;
2231                    requestedPackage = r.requestedVrComponent;
2232                    userId = r.userId;
2233                    callingPackage = r.info.getComponentName();
2234                    if (mInVrMode != vrMode) {
2235                        mInVrMode = vrMode;
2236                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2237                        if (r.app != null) {
2238                            ProcessRecord proc = r.app;
2239                            if (proc.vrThreadTid > 0) {
2240                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2241                                    try {
2242                                        if (mInVrMode == true) {
2243                                            Process.setThreadScheduler(proc.vrThreadTid,
2244                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2245                                        } else {
2246                                            Process.setThreadScheduler(proc.vrThreadTid,
2247                                                Process.SCHED_OTHER, 0);
2248                                        }
2249                                    } catch (IllegalArgumentException e) {
2250                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2251                                                + " not exist:\n" + e);
2252                                    }
2253                                }
2254                            }
2255                        }
2256                    }
2257                }
2258                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2259            } break;
2260            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2261                final ActivityRecord r = (ActivityRecord) msg.obj;
2262                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2263                if (needsVrMode) {
2264                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2265                            r.info.getComponentName(), false);
2266                }
2267            } break;
2268            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2269                synchronized (ActivityManagerService.this) {
2270                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2271                        ProcessRecord r = mLruProcesses.get(i);
2272                        if (r.thread != null) {
2273                            try {
2274                                r.thread.handleTrustStorageUpdate();
2275                            } catch (RemoteException ex) {
2276                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2277                                        r.info.processName);
2278                            }
2279                        }
2280                    }
2281                }
2282            } break;
2283            }
2284        }
2285    };
2286
2287    static final int COLLECT_PSS_BG_MSG = 1;
2288
2289    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2290        @Override
2291        public void handleMessage(Message msg) {
2292            switch (msg.what) {
2293            case COLLECT_PSS_BG_MSG: {
2294                long start = SystemClock.uptimeMillis();
2295                MemInfoReader memInfo = null;
2296                synchronized (ActivityManagerService.this) {
2297                    if (mFullPssPending) {
2298                        mFullPssPending = false;
2299                        memInfo = new MemInfoReader();
2300                    }
2301                }
2302                if (memInfo != null) {
2303                    updateCpuStatsNow();
2304                    long nativeTotalPss = 0;
2305                    final List<ProcessCpuTracker.Stats> stats;
2306                    synchronized (mProcessCpuTracker) {
2307                        stats = mProcessCpuTracker.getStats( (st)-> {
2308                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2309                        });
2310                    }
2311                    final int N = stats.size();
2312                    for (int j = 0; j < N; j++) {
2313                        synchronized (mPidsSelfLocked) {
2314                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2315                                // This is one of our own processes; skip it.
2316                                continue;
2317                            }
2318                        }
2319                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2320                    }
2321                    memInfo.readMemInfo();
2322                    synchronized (ActivityManagerService.this) {
2323                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2324                                + (SystemClock.uptimeMillis()-start) + "ms");
2325                        final long cachedKb = memInfo.getCachedSizeKb();
2326                        final long freeKb = memInfo.getFreeSizeKb();
2327                        final long zramKb = memInfo.getZramTotalSizeKb();
2328                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2329                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2330                                kernelKb*1024, nativeTotalPss*1024);
2331                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2332                                nativeTotalPss);
2333                    }
2334                }
2335
2336                int num = 0;
2337                long[] tmp = new long[2];
2338                do {
2339                    ProcessRecord proc;
2340                    int procState;
2341                    int pid;
2342                    long lastPssTime;
2343                    synchronized (ActivityManagerService.this) {
2344                        if (mPendingPssProcesses.size() <= 0) {
2345                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2346                                    "Collected PSS of " + num + " processes in "
2347                                    + (SystemClock.uptimeMillis() - start) + "ms");
2348                            mPendingPssProcesses.clear();
2349                            return;
2350                        }
2351                        proc = mPendingPssProcesses.remove(0);
2352                        procState = proc.pssProcState;
2353                        lastPssTime = proc.lastPssTime;
2354                        if (proc.thread != null && procState == proc.setProcState
2355                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2356                                        < SystemClock.uptimeMillis()) {
2357                            pid = proc.pid;
2358                        } else {
2359                            proc = null;
2360                            pid = 0;
2361                        }
2362                    }
2363                    if (proc != null) {
2364                        long pss = Debug.getPss(pid, tmp, null);
2365                        synchronized (ActivityManagerService.this) {
2366                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2367                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2368                                num++;
2369                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2370                                        SystemClock.uptimeMillis());
2371                            }
2372                        }
2373                    }
2374                } while (true);
2375            }
2376            }
2377        }
2378    };
2379
2380    public void setSystemProcess() {
2381        try {
2382            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2383            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2384            ServiceManager.addService("meminfo", new MemBinder(this));
2385            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2386            ServiceManager.addService("dbinfo", new DbBinder(this));
2387            if (MONITOR_CPU_USAGE) {
2388                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2389            }
2390            ServiceManager.addService("permission", new PermissionController(this));
2391            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2392
2393            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2394                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2395            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2396
2397            synchronized (this) {
2398                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2399                app.persistent = true;
2400                app.pid = MY_PID;
2401                app.maxAdj = ProcessList.SYSTEM_ADJ;
2402                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2403                synchronized (mPidsSelfLocked) {
2404                    mPidsSelfLocked.put(app.pid, app);
2405                }
2406                updateLruProcessLocked(app, false, null);
2407                updateOomAdjLocked();
2408            }
2409        } catch (PackageManager.NameNotFoundException e) {
2410            throw new RuntimeException(
2411                    "Unable to find android system package", e);
2412        }
2413    }
2414
2415    public void setWindowManager(WindowManagerService wm) {
2416        mWindowManager = wm;
2417        mStackSupervisor.setWindowManager(wm);
2418        mActivityStarter.setWindowManager(wm);
2419    }
2420
2421    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2422        mUsageStatsService = usageStatsManager;
2423    }
2424
2425    public void startObservingNativeCrashes() {
2426        final NativeCrashListener ncl = new NativeCrashListener(this);
2427        ncl.start();
2428    }
2429
2430    public IAppOpsService getAppOpsService() {
2431        return mAppOpsService;
2432    }
2433
2434    static class MemBinder extends Binder {
2435        ActivityManagerService mActivityManagerService;
2436        MemBinder(ActivityManagerService activityManagerService) {
2437            mActivityManagerService = activityManagerService;
2438        }
2439
2440        @Override
2441        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2442            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2443                    != PackageManager.PERMISSION_GRANTED) {
2444                pw.println("Permission Denial: can't dump meminfo from from pid="
2445                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2446                        + " without permission " + android.Manifest.permission.DUMP);
2447                return;
2448            }
2449
2450            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2451        }
2452    }
2453
2454    static class GraphicsBinder extends Binder {
2455        ActivityManagerService mActivityManagerService;
2456        GraphicsBinder(ActivityManagerService activityManagerService) {
2457            mActivityManagerService = activityManagerService;
2458        }
2459
2460        @Override
2461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                    != PackageManager.PERMISSION_GRANTED) {
2464                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                        + " without permission " + android.Manifest.permission.DUMP);
2467                return;
2468            }
2469
2470            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2471        }
2472    }
2473
2474    static class DbBinder extends Binder {
2475        ActivityManagerService mActivityManagerService;
2476        DbBinder(ActivityManagerService activityManagerService) {
2477            mActivityManagerService = activityManagerService;
2478        }
2479
2480        @Override
2481        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                    != PackageManager.PERMISSION_GRANTED) {
2484                pw.println("Permission Denial: can't dump dbinfo from from pid="
2485                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                        + " without permission " + android.Manifest.permission.DUMP);
2487                return;
2488            }
2489
2490            mActivityManagerService.dumpDbInfo(fd, pw, args);
2491        }
2492    }
2493
2494    static class CpuBinder extends Binder {
2495        ActivityManagerService mActivityManagerService;
2496        CpuBinder(ActivityManagerService activityManagerService) {
2497            mActivityManagerService = activityManagerService;
2498        }
2499
2500        @Override
2501        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2502            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2503                    != PackageManager.PERMISSION_GRANTED) {
2504                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2505                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2506                        + " without permission " + android.Manifest.permission.DUMP);
2507                return;
2508            }
2509
2510            synchronized (mActivityManagerService.mProcessCpuTracker) {
2511                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2512                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2513                        SystemClock.uptimeMillis()));
2514            }
2515        }
2516    }
2517
2518    public static final class Lifecycle extends SystemService {
2519        private final ActivityManagerService mService;
2520
2521        public Lifecycle(Context context) {
2522            super(context);
2523            mService = new ActivityManagerService(context);
2524        }
2525
2526        @Override
2527        public void onStart() {
2528            mService.start();
2529        }
2530
2531        public ActivityManagerService getService() {
2532            return mService;
2533        }
2534    }
2535
2536    // Note: This method is invoked on the main thread but may need to attach various
2537    // handlers to other threads.  So take care to be explicit about the looper.
2538    public ActivityManagerService(Context systemContext) {
2539        mContext = systemContext;
2540        mFactoryTest = FactoryTest.getMode();
2541        mSystemThread = ActivityThread.currentActivityThread();
2542
2543        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2544
2545        mPermissionReviewRequired = mContext.getResources().getBoolean(
2546                com.android.internal.R.bool.config_permissionReviewRequired);
2547
2548        mHandlerThread = new ServiceThread(TAG,
2549                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2550        mHandlerThread.start();
2551        mHandler = new MainHandler(mHandlerThread.getLooper());
2552        mUiHandler = new UiHandler();
2553
2554        /* static; one-time init here */
2555        if (sKillHandler == null) {
2556            sKillThread = new ServiceThread(TAG + ":kill",
2557                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2558            sKillThread.start();
2559            sKillHandler = new KillHandler(sKillThread.getLooper());
2560        }
2561
2562        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2563                "foreground", BROADCAST_FG_TIMEOUT, false);
2564        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2565                "background", BROADCAST_BG_TIMEOUT, true);
2566        mBroadcastQueues[0] = mFgBroadcastQueue;
2567        mBroadcastQueues[1] = mBgBroadcastQueue;
2568
2569        mServices = new ActiveServices(this);
2570        mProviderMap = new ProviderMap(this);
2571        mAppErrors = new AppErrors(mContext, this);
2572
2573        // TODO: Move creation of battery stats service outside of activity manager service.
2574        File dataDir = Environment.getDataDirectory();
2575        File systemDir = new File(dataDir, "system");
2576        systemDir.mkdirs();
2577        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2578        mBatteryStatsService.getActiveStatistics().readLocked();
2579        mBatteryStatsService.scheduleWriteToDisk();
2580        mOnBattery = DEBUG_POWER ? true
2581                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2582        mBatteryStatsService.getActiveStatistics().setCallback(this);
2583
2584        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2585
2586        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2587        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2588                new IAppOpsCallback.Stub() {
2589                    @Override public void opChanged(int op, int uid, String packageName) {
2590                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2591                            if (mAppOpsService.checkOperation(op, uid, packageName)
2592                                    != AppOpsManager.MODE_ALLOWED) {
2593                                runInBackgroundDisabled(uid);
2594                            }
2595                        }
2596                    }
2597                });
2598
2599        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2600
2601        mUserController = new UserController(this);
2602
2603        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2604            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2605
2606        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2607            mUseFifoUiScheduling = true;
2608        }
2609
2610        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2611
2612        mTempConfig.setToDefaults();
2613        mTempConfig.setLocales(LocaleList.getDefault());
2614        mConfigurationSeq = mTempConfig.seq = 1;
2615
2616        mProcessCpuTracker.init();
2617
2618        mStackSupervisor = new ActivityStackSupervisor(this);
2619        mStackSupervisor.onConfigurationChanged(mTempConfig);
2620        mKeyguardController = mStackSupervisor.mKeyguardController;
2621        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2622        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2623        mTaskChangeNotificationController =
2624                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2625        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2626        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2627
2628        mProcessCpuThread = new Thread("CpuTracker") {
2629            @Override
2630            public void run() {
2631                while (true) {
2632                    try {
2633                        try {
2634                            synchronized(this) {
2635                                final long now = SystemClock.uptimeMillis();
2636                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2637                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2638                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2639                                //        + ", write delay=" + nextWriteDelay);
2640                                if (nextWriteDelay < nextCpuDelay) {
2641                                    nextCpuDelay = nextWriteDelay;
2642                                }
2643                                if (nextCpuDelay > 0) {
2644                                    mProcessCpuMutexFree.set(true);
2645                                    this.wait(nextCpuDelay);
2646                                }
2647                            }
2648                        } catch (InterruptedException e) {
2649                        }
2650                        updateCpuStatsNow();
2651                    } catch (Exception e) {
2652                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2653                    }
2654                }
2655            }
2656        };
2657
2658        Watchdog.getInstance().addMonitor(this);
2659        Watchdog.getInstance().addThread(mHandler);
2660    }
2661
2662    public void setSystemServiceManager(SystemServiceManager mgr) {
2663        mSystemServiceManager = mgr;
2664    }
2665
2666    public void setInstaller(Installer installer) {
2667        mInstaller = installer;
2668    }
2669
2670    private void start() {
2671        Process.removeAllProcessGroups();
2672        mProcessCpuThread.start();
2673
2674        mBatteryStatsService.publish(mContext);
2675        mAppOpsService.publish(mContext);
2676        Slog.d("AppOps", "AppOpsService published");
2677        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2678    }
2679
2680    void onUserStoppedLocked(int userId) {
2681        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2682    }
2683
2684    public void initPowerManagement() {
2685        mStackSupervisor.initPowerManagement();
2686        mBatteryStatsService.initPowerManagement();
2687        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2688        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2689        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2690        mVoiceWakeLock.setReferenceCounted(false);
2691    }
2692
2693    @Override
2694    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2695            throws RemoteException {
2696        if (code == SYSPROPS_TRANSACTION) {
2697            // We need to tell all apps about the system property change.
2698            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2699            synchronized(this) {
2700                final int NP = mProcessNames.getMap().size();
2701                for (int ip=0; ip<NP; ip++) {
2702                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2703                    final int NA = apps.size();
2704                    for (int ia=0; ia<NA; ia++) {
2705                        ProcessRecord app = apps.valueAt(ia);
2706                        if (app.thread != null) {
2707                            procs.add(app.thread.asBinder());
2708                        }
2709                    }
2710                }
2711            }
2712
2713            int N = procs.size();
2714            for (int i=0; i<N; i++) {
2715                Parcel data2 = Parcel.obtain();
2716                try {
2717                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2718                } catch (RemoteException e) {
2719                }
2720                data2.recycle();
2721            }
2722        }
2723        try {
2724            return super.onTransact(code, data, reply, flags);
2725        } catch (RuntimeException e) {
2726            // The activity manager only throws security exceptions, so let's
2727            // log all others.
2728            if (!(e instanceof SecurityException)) {
2729                Slog.wtf(TAG, "Activity Manager Crash", e);
2730            }
2731            throw e;
2732        }
2733    }
2734
2735    void updateCpuStats() {
2736        final long now = SystemClock.uptimeMillis();
2737        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2738            return;
2739        }
2740        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2741            synchronized (mProcessCpuThread) {
2742                mProcessCpuThread.notify();
2743            }
2744        }
2745    }
2746
2747    void updateCpuStatsNow() {
2748        synchronized (mProcessCpuTracker) {
2749            mProcessCpuMutexFree.set(false);
2750            final long now = SystemClock.uptimeMillis();
2751            boolean haveNewCpuStats = false;
2752
2753            if (MONITOR_CPU_USAGE &&
2754                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2755                mLastCpuTime.set(now);
2756                mProcessCpuTracker.update();
2757                if (mProcessCpuTracker.hasGoodLastStats()) {
2758                    haveNewCpuStats = true;
2759                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2760                    //Slog.i(TAG, "Total CPU usage: "
2761                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2762
2763                    // Slog the cpu usage if the property is set.
2764                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2765                        int user = mProcessCpuTracker.getLastUserTime();
2766                        int system = mProcessCpuTracker.getLastSystemTime();
2767                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2768                        int irq = mProcessCpuTracker.getLastIrqTime();
2769                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2770                        int idle = mProcessCpuTracker.getLastIdleTime();
2771
2772                        int total = user + system + iowait + irq + softIrq + idle;
2773                        if (total == 0) total = 1;
2774
2775                        EventLog.writeEvent(EventLogTags.CPU,
2776                                ((user+system+iowait+irq+softIrq) * 100) / total,
2777                                (user * 100) / total,
2778                                (system * 100) / total,
2779                                (iowait * 100) / total,
2780                                (irq * 100) / total,
2781                                (softIrq * 100) / total);
2782                    }
2783                }
2784            }
2785
2786            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2787            synchronized(bstats) {
2788                synchronized(mPidsSelfLocked) {
2789                    if (haveNewCpuStats) {
2790                        if (bstats.startAddingCpuLocked()) {
2791                            int totalUTime = 0;
2792                            int totalSTime = 0;
2793                            final int N = mProcessCpuTracker.countStats();
2794                            for (int i=0; i<N; i++) {
2795                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2796                                if (!st.working) {
2797                                    continue;
2798                                }
2799                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2800                                totalUTime += st.rel_utime;
2801                                totalSTime += st.rel_stime;
2802                                if (pr != null) {
2803                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2804                                    if (ps == null || !ps.isActive()) {
2805                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2806                                                pr.info.uid, pr.processName);
2807                                    }
2808                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2809                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2810                                } else {
2811                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2812                                    if (ps == null || !ps.isActive()) {
2813                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2814                                                bstats.mapUid(st.uid), st.name);
2815                                    }
2816                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2817                                }
2818                            }
2819                            final int userTime = mProcessCpuTracker.getLastUserTime();
2820                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2821                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2822                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2823                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2824                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2825                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2826                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2827                        }
2828                    }
2829                }
2830
2831                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2832                    mLastWriteTime = now;
2833                    mBatteryStatsService.scheduleWriteToDisk();
2834                }
2835            }
2836        }
2837    }
2838
2839    @Override
2840    public void batteryNeedsCpuUpdate() {
2841        updateCpuStatsNow();
2842    }
2843
2844    @Override
2845    public void batteryPowerChanged(boolean onBattery) {
2846        // When plugging in, update the CPU stats first before changing
2847        // the plug state.
2848        updateCpuStatsNow();
2849        synchronized (this) {
2850            synchronized(mPidsSelfLocked) {
2851                mOnBattery = DEBUG_POWER ? true : onBattery;
2852            }
2853        }
2854    }
2855
2856    @Override
2857    public void batterySendBroadcast(Intent intent) {
2858        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2859                AppOpsManager.OP_NONE, null, false, false,
2860                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2861    }
2862
2863    /**
2864     * Initialize the application bind args. These are passed to each
2865     * process when the bindApplication() IPC is sent to the process. They're
2866     * lazily setup to make sure the services are running when they're asked for.
2867     */
2868    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2869        // Isolated processes won't get this optimization, so that we don't
2870        // violate the rules about which services they have access to.
2871        if (isolated) {
2872            if (mIsolatedAppBindArgs == null) {
2873                mIsolatedAppBindArgs = new HashMap<>();
2874                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2875            }
2876            return mIsolatedAppBindArgs;
2877        }
2878
2879        if (mAppBindArgs == null) {
2880            mAppBindArgs = new HashMap<>();
2881
2882            // Setup the application init args
2883            mAppBindArgs.put("package", ServiceManager.getService("package"));
2884            mAppBindArgs.put("window", ServiceManager.getService("window"));
2885            mAppBindArgs.put(Context.ALARM_SERVICE,
2886                    ServiceManager.getService(Context.ALARM_SERVICE));
2887        }
2888        return mAppBindArgs;
2889    }
2890
2891    /**
2892     * Update AMS states when an activity is resumed. This should only be called by
2893     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2894     */
2895    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2896        if (r.task.isApplicationTask()) {
2897            if (mCurAppTimeTracker != r.appTimeTracker) {
2898                // We are switching app tracking.  Complete the current one.
2899                if (mCurAppTimeTracker != null) {
2900                    mCurAppTimeTracker.stop();
2901                    mHandler.obtainMessage(
2902                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2903                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2904                    mCurAppTimeTracker = null;
2905                }
2906                if (r.appTimeTracker != null) {
2907                    mCurAppTimeTracker = r.appTimeTracker;
2908                    startTimeTrackingFocusedActivityLocked();
2909                }
2910            } else {
2911                startTimeTrackingFocusedActivityLocked();
2912            }
2913        } else {
2914            r.appTimeTracker = null;
2915        }
2916        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2917        // TODO: Probably not, because we don't want to resume voice on switching
2918        // back to this activity
2919        if (r.task.voiceInteractor != null) {
2920            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2921        } else {
2922            finishRunningVoiceLocked();
2923            IVoiceInteractionSession session;
2924            if (mLastResumedActivity != null
2925                    && ((session = mLastResumedActivity.task.voiceSession) != null
2926                    || (session = mLastResumedActivity.voiceSession) != null)) {
2927                // We had been in a voice interaction session, but now focused has
2928                // move to something different.  Just finish the session, we can't
2929                // return to it and retain the proper state and synchronization with
2930                // the voice interaction service.
2931                finishVoiceTask(session);
2932            }
2933        }
2934
2935        mWindowManager.setFocusedApp(r.appToken, true);
2936
2937        applyUpdateLockStateLocked(r);
2938        applyUpdateVrModeLocked(r);
2939        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2940            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2941            mHandler.obtainMessage(
2942                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
2943        }
2944
2945        mLastResumedActivity = r;
2946
2947        EventLogTags.writeAmSetResumedActivity(
2948                r == null ? -1 : r.userId,
2949                r == null ? "NULL" : r.shortComponentName,
2950                reason);
2951    }
2952
2953    @Override
2954    public void setFocusedStack(int stackId) {
2955        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2956        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2957        final long callingId = Binder.clearCallingIdentity();
2958        try {
2959            synchronized (this) {
2960                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2961                if (stack == null) {
2962                    return;
2963                }
2964                final ActivityRecord r = stack.topRunningActivityLocked();
2965                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
2966                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2967                }
2968            }
2969        } finally {
2970            Binder.restoreCallingIdentity(callingId);
2971        }
2972    }
2973
2974    @Override
2975    public void setFocusedTask(int taskId) {
2976        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2977        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2978        final long callingId = Binder.clearCallingIdentity();
2979        try {
2980            synchronized (this) {
2981                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2982                if (task == null) {
2983                    return;
2984                }
2985                final ActivityRecord r = task.topRunningActivityLocked();
2986                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
2987                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2988                }
2989            }
2990        } finally {
2991            Binder.restoreCallingIdentity(callingId);
2992        }
2993    }
2994
2995    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2996    @Override
2997    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2998        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2999        mTaskChangeNotificationController.registerTaskStackListener(listener);
3000    }
3001
3002    /**
3003     * Unregister a task stack listener so that it stops receiving callbacks.
3004     */
3005    @Override
3006    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3007         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3008         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3009     }
3010
3011    @Override
3012    public void notifyActivityDrawn(IBinder token) {
3013        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3014        synchronized (this) {
3015            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3016            if (r != null) {
3017                r.getStack().notifyActivityDrawnLocked(r);
3018            }
3019        }
3020    }
3021
3022    final void applyUpdateLockStateLocked(ActivityRecord r) {
3023        // Modifications to the UpdateLock state are done on our handler, outside
3024        // the activity manager's locks.  The new state is determined based on the
3025        // state *now* of the relevant activity record.  The object is passed to
3026        // the handler solely for logging detail, not to be consulted/modified.
3027        final boolean nextState = r != null && r.immersive;
3028        mHandler.sendMessage(
3029                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3030    }
3031
3032    final void applyUpdateVrModeLocked(ActivityRecord r) {
3033        mHandler.sendMessage(
3034                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3035    }
3036
3037    void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3038        mHandler.sendMessage(
3039                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3040    }
3041
3042    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3043            ComponentName callingPackage, boolean immediate) {
3044        VrManagerInternal vrService =
3045                LocalServices.getService(VrManagerInternal.class);
3046        if (immediate) {
3047            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3048        } else {
3049            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3050        }
3051    }
3052
3053    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3054        Message msg = Message.obtain();
3055        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3056        msg.obj = r.task.askedCompatMode ? null : r;
3057        mUiHandler.sendMessage(msg);
3058    }
3059
3060    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3061        final Configuration globalConfig = getGlobalConfiguration();
3062        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3063                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3064            final Message msg = Message.obtain();
3065            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3066            msg.obj = r;
3067            mUiHandler.sendMessage(msg);
3068        }
3069    }
3070
3071    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3072            String what, Object obj, ProcessRecord srcApp) {
3073        app.lastActivityTime = now;
3074
3075        if (app.activities.size() > 0) {
3076            // Don't want to touch dependent processes that are hosting activities.
3077            return index;
3078        }
3079
3080        int lrui = mLruProcesses.lastIndexOf(app);
3081        if (lrui < 0) {
3082            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3083                    + what + " " + obj + " from " + srcApp);
3084            return index;
3085        }
3086
3087        if (lrui >= index) {
3088            // Don't want to cause this to move dependent processes *back* in the
3089            // list as if they were less frequently used.
3090            return index;
3091        }
3092
3093        if (lrui >= mLruProcessActivityStart) {
3094            // Don't want to touch dependent processes that are hosting activities.
3095            return index;
3096        }
3097
3098        mLruProcesses.remove(lrui);
3099        if (index > 0) {
3100            index--;
3101        }
3102        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3103                + " in LRU list: " + app);
3104        mLruProcesses.add(index, app);
3105        return index;
3106    }
3107
3108    static void killProcessGroup(int uid, int pid) {
3109        if (sKillHandler != null) {
3110            sKillHandler.sendMessage(
3111                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3112        } else {
3113            Slog.w(TAG, "Asked to kill process group before system bringup!");
3114            Process.killProcessGroup(uid, pid);
3115        }
3116    }
3117
3118    final void removeLruProcessLocked(ProcessRecord app) {
3119        int lrui = mLruProcesses.lastIndexOf(app);
3120        if (lrui >= 0) {
3121            if (!app.killed) {
3122                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3123                Process.killProcessQuiet(app.pid);
3124                killProcessGroup(app.uid, app.pid);
3125            }
3126            if (lrui <= mLruProcessActivityStart) {
3127                mLruProcessActivityStart--;
3128            }
3129            if (lrui <= mLruProcessServiceStart) {
3130                mLruProcessServiceStart--;
3131            }
3132            mLruProcesses.remove(lrui);
3133        }
3134    }
3135
3136    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3137            ProcessRecord client) {
3138        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3139                || app.treatLikeActivity;
3140        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3141        if (!activityChange && hasActivity) {
3142            // The process has activities, so we are only allowing activity-based adjustments
3143            // to move it.  It should be kept in the front of the list with other
3144            // processes that have activities, and we don't want those to change their
3145            // order except due to activity operations.
3146            return;
3147        }
3148
3149        mLruSeq++;
3150        final long now = SystemClock.uptimeMillis();
3151        app.lastActivityTime = now;
3152
3153        // First a quick reject: if the app is already at the position we will
3154        // put it, then there is nothing to do.
3155        if (hasActivity) {
3156            final int N = mLruProcesses.size();
3157            if (N > 0 && mLruProcesses.get(N-1) == app) {
3158                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3159                return;
3160            }
3161        } else {
3162            if (mLruProcessServiceStart > 0
3163                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3164                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3165                return;
3166            }
3167        }
3168
3169        int lrui = mLruProcesses.lastIndexOf(app);
3170
3171        if (app.persistent && lrui >= 0) {
3172            // We don't care about the position of persistent processes, as long as
3173            // they are in the list.
3174            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3175            return;
3176        }
3177
3178        /* In progress: compute new position first, so we can avoid doing work
3179           if the process is not actually going to move.  Not yet working.
3180        int addIndex;
3181        int nextIndex;
3182        boolean inActivity = false, inService = false;
3183        if (hasActivity) {
3184            // Process has activities, put it at the very tipsy-top.
3185            addIndex = mLruProcesses.size();
3186            nextIndex = mLruProcessServiceStart;
3187            inActivity = true;
3188        } else if (hasService) {
3189            // Process has services, put it at the top of the service list.
3190            addIndex = mLruProcessActivityStart;
3191            nextIndex = mLruProcessServiceStart;
3192            inActivity = true;
3193            inService = true;
3194        } else  {
3195            // Process not otherwise of interest, it goes to the top of the non-service area.
3196            addIndex = mLruProcessServiceStart;
3197            if (client != null) {
3198                int clientIndex = mLruProcesses.lastIndexOf(client);
3199                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3200                        + app);
3201                if (clientIndex >= 0 && addIndex > clientIndex) {
3202                    addIndex = clientIndex;
3203                }
3204            }
3205            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3206        }
3207
3208        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3209                + mLruProcessActivityStart + "): " + app);
3210        */
3211
3212        if (lrui >= 0) {
3213            if (lrui < mLruProcessActivityStart) {
3214                mLruProcessActivityStart--;
3215            }
3216            if (lrui < mLruProcessServiceStart) {
3217                mLruProcessServiceStart--;
3218            }
3219            /*
3220            if (addIndex > lrui) {
3221                addIndex--;
3222            }
3223            if (nextIndex > lrui) {
3224                nextIndex--;
3225            }
3226            */
3227            mLruProcesses.remove(lrui);
3228        }
3229
3230        /*
3231        mLruProcesses.add(addIndex, app);
3232        if (inActivity) {
3233            mLruProcessActivityStart++;
3234        }
3235        if (inService) {
3236            mLruProcessActivityStart++;
3237        }
3238        */
3239
3240        int nextIndex;
3241        if (hasActivity) {
3242            final int N = mLruProcesses.size();
3243            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3244                // Process doesn't have activities, but has clients with
3245                // activities...  move it up, but one below the top (the top
3246                // should always have a real activity).
3247                if (DEBUG_LRU) Slog.d(TAG_LRU,
3248                        "Adding to second-top of LRU activity list: " + app);
3249                mLruProcesses.add(N - 1, app);
3250                // To keep it from spamming the LRU list (by making a bunch of clients),
3251                // we will push down any other entries owned by the app.
3252                final int uid = app.info.uid;
3253                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3254                    ProcessRecord subProc = mLruProcesses.get(i);
3255                    if (subProc.info.uid == uid) {
3256                        // We want to push this one down the list.  If the process after
3257                        // it is for the same uid, however, don't do so, because we don't
3258                        // want them internally to be re-ordered.
3259                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3260                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3261                                    "Pushing uid " + uid + " swapping at " + i + ": "
3262                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3263                            ProcessRecord tmp = mLruProcesses.get(i);
3264                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3265                            mLruProcesses.set(i - 1, tmp);
3266                            i--;
3267                        }
3268                    } else {
3269                        // A gap, we can stop here.
3270                        break;
3271                    }
3272                }
3273            } else {
3274                // Process has activities, put it at the very tipsy-top.
3275                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3276                mLruProcesses.add(app);
3277            }
3278            nextIndex = mLruProcessServiceStart;
3279        } else if (hasService) {
3280            // Process has services, put it at the top of the service list.
3281            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3282            mLruProcesses.add(mLruProcessActivityStart, app);
3283            nextIndex = mLruProcessServiceStart;
3284            mLruProcessActivityStart++;
3285        } else  {
3286            // Process not otherwise of interest, it goes to the top of the non-service area.
3287            int index = mLruProcessServiceStart;
3288            if (client != null) {
3289                // If there is a client, don't allow the process to be moved up higher
3290                // in the list than that client.
3291                int clientIndex = mLruProcesses.lastIndexOf(client);
3292                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3293                        + " when updating " + app);
3294                if (clientIndex <= lrui) {
3295                    // Don't allow the client index restriction to push it down farther in the
3296                    // list than it already is.
3297                    clientIndex = lrui;
3298                }
3299                if (clientIndex >= 0 && index > clientIndex) {
3300                    index = clientIndex;
3301                }
3302            }
3303            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3304            mLruProcesses.add(index, app);
3305            nextIndex = index-1;
3306            mLruProcessActivityStart++;
3307            mLruProcessServiceStart++;
3308        }
3309
3310        // If the app is currently using a content provider or service,
3311        // bump those processes as well.
3312        for (int j=app.connections.size()-1; j>=0; j--) {
3313            ConnectionRecord cr = app.connections.valueAt(j);
3314            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3315                    && cr.binding.service.app != null
3316                    && cr.binding.service.app.lruSeq != mLruSeq
3317                    && !cr.binding.service.app.persistent) {
3318                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3319                        "service connection", cr, app);
3320            }
3321        }
3322        for (int j=app.conProviders.size()-1; j>=0; j--) {
3323            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3324            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3325                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3326                        "provider reference", cpr, app);
3327            }
3328        }
3329    }
3330
3331    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3332        if (uid == Process.SYSTEM_UID) {
3333            // The system gets to run in any process.  If there are multiple
3334            // processes with the same uid, just pick the first (this
3335            // should never happen).
3336            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3337            if (procs == null) return null;
3338            final int procCount = procs.size();
3339            for (int i = 0; i < procCount; i++) {
3340                final int procUid = procs.keyAt(i);
3341                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3342                    // Don't use an app process or different user process for system component.
3343                    continue;
3344                }
3345                return procs.valueAt(i);
3346            }
3347        }
3348        ProcessRecord proc = mProcessNames.get(processName, uid);
3349        if (false && proc != null && !keepIfLarge
3350                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3351                && proc.lastCachedPss >= 4000) {
3352            // Turn this condition on to cause killing to happen regularly, for testing.
3353            if (proc.baseProcessTracker != null) {
3354                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3355            }
3356            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3357        } else if (proc != null && !keepIfLarge
3358                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3359                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3360            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3361            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3362                if (proc.baseProcessTracker != null) {
3363                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3364                }
3365                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3366            }
3367        }
3368        return proc;
3369    }
3370
3371    void notifyPackageUse(String packageName, int reason) {
3372        IPackageManager pm = AppGlobals.getPackageManager();
3373        try {
3374            pm.notifyPackageUse(packageName, reason);
3375        } catch (RemoteException e) {
3376        }
3377    }
3378
3379    boolean isNextTransitionForward() {
3380        int transit = mWindowManager.getPendingAppTransition();
3381        return transit == TRANSIT_ACTIVITY_OPEN
3382                || transit == TRANSIT_TASK_OPEN
3383                || transit == TRANSIT_TASK_TO_FRONT;
3384    }
3385
3386    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3387            String processName, String abiOverride, int uid, Runnable crashHandler) {
3388        synchronized(this) {
3389            ApplicationInfo info = new ApplicationInfo();
3390            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3391            // For isolated processes, the former contains the parent's uid and the latter the
3392            // actual uid of the isolated process.
3393            // In the special case introduced by this method (which is, starting an isolated
3394            // process directly from the SystemServer without an actual parent app process) the
3395            // closest thing to a parent's uid is SYSTEM_UID.
3396            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3397            // the |isolated| logic in the ProcessRecord constructor.
3398            info.uid = Process.SYSTEM_UID;
3399            info.processName = processName;
3400            info.className = entryPoint;
3401            info.packageName = "android";
3402            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3403                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3404                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3405                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3406                    crashHandler);
3407            return proc != null ? proc.pid : 0;
3408        }
3409    }
3410
3411    final ProcessRecord startProcessLocked(String processName,
3412            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3413            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3414            boolean isolated, boolean keepIfLarge) {
3415        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3416                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3417                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3418                null /* crashHandler */);
3419    }
3420
3421    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3422            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3423            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3424            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3425        long startTime = SystemClock.elapsedRealtime();
3426        ProcessRecord app;
3427        if (!isolated) {
3428            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3429            checkTime(startTime, "startProcess: after getProcessRecord");
3430
3431            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3432                // If we are in the background, then check to see if this process
3433                // is bad.  If so, we will just silently fail.
3434                if (mAppErrors.isBadProcessLocked(info)) {
3435                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3436                            + "/" + info.processName);
3437                    return null;
3438                }
3439            } else {
3440                // When the user is explicitly starting a process, then clear its
3441                // crash count so that we won't make it bad until they see at
3442                // least one crash dialog again, and make the process good again
3443                // if it had been bad.
3444                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3445                        + "/" + info.processName);
3446                mAppErrors.resetProcessCrashTimeLocked(info);
3447                if (mAppErrors.isBadProcessLocked(info)) {
3448                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3449                            UserHandle.getUserId(info.uid), info.uid,
3450                            info.processName);
3451                    mAppErrors.clearBadProcessLocked(info);
3452                    if (app != null) {
3453                        app.bad = false;
3454                    }
3455                }
3456            }
3457        } else {
3458            // If this is an isolated process, it can't re-use an existing process.
3459            app = null;
3460        }
3461
3462        // We don't have to do anything more if:
3463        // (1) There is an existing application record; and
3464        // (2) The caller doesn't think it is dead, OR there is no thread
3465        //     object attached to it so we know it couldn't have crashed; and
3466        // (3) There is a pid assigned to it, so it is either starting or
3467        //     already running.
3468        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3469                + " app=" + app + " knownToBeDead=" + knownToBeDead
3470                + " thread=" + (app != null ? app.thread : null)
3471                + " pid=" + (app != null ? app.pid : -1));
3472        if (app != null && app.pid > 0) {
3473            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3474                // We already have the app running, or are waiting for it to
3475                // come up (we have a pid but not yet its thread), so keep it.
3476                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3477                // If this is a new package in the process, add the package to the list
3478                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3479                checkTime(startTime, "startProcess: done, added package to proc");
3480                return app;
3481            }
3482
3483            // An application record is attached to a previous process,
3484            // clean it up now.
3485            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3486            checkTime(startTime, "startProcess: bad proc running, killing");
3487            killProcessGroup(app.uid, app.pid);
3488            handleAppDiedLocked(app, true, true);
3489            checkTime(startTime, "startProcess: done killing old proc");
3490        }
3491
3492        String hostingNameStr = hostingName != null
3493                ? hostingName.flattenToShortString() : null;
3494
3495        if (app == null) {
3496            checkTime(startTime, "startProcess: creating new process record");
3497            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3498            if (app == null) {
3499                Slog.w(TAG, "Failed making new process record for "
3500                        + processName + "/" + info.uid + " isolated=" + isolated);
3501                return null;
3502            }
3503            app.crashHandler = crashHandler;
3504            checkTime(startTime, "startProcess: done creating new process record");
3505        } else {
3506            // If this is a new package in the process, add the package to the list
3507            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3508            checkTime(startTime, "startProcess: added package to existing proc");
3509        }
3510
3511        // If the system is not ready yet, then hold off on starting this
3512        // process until it is.
3513        if (!mProcessesReady
3514                && !isAllowedWhileBooting(info)
3515                && !allowWhileBooting) {
3516            if (!mProcessesOnHold.contains(app)) {
3517                mProcessesOnHold.add(app);
3518            }
3519            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3520                    "System not ready, putting on hold: " + app);
3521            checkTime(startTime, "startProcess: returning with proc on hold");
3522            return app;
3523        }
3524
3525        checkTime(startTime, "startProcess: stepping in to startProcess");
3526        startProcessLocked(
3527                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3528        checkTime(startTime, "startProcess: done starting proc!");
3529        return (app.pid != 0) ? app : null;
3530    }
3531
3532    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3533        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3534    }
3535
3536    private final void startProcessLocked(ProcessRecord app,
3537            String hostingType, String hostingNameStr) {
3538        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3539                null /* entryPoint */, null /* entryPointArgs */);
3540    }
3541
3542    private final void startProcessLocked(ProcessRecord app, String hostingType,
3543            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3544        long startTime = SystemClock.elapsedRealtime();
3545        if (app.pid > 0 && app.pid != MY_PID) {
3546            checkTime(startTime, "startProcess: removing from pids map");
3547            synchronized (mPidsSelfLocked) {
3548                mPidsSelfLocked.remove(app.pid);
3549                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3550            }
3551            checkTime(startTime, "startProcess: done removing from pids map");
3552            app.setPid(0);
3553        }
3554
3555        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3556                "startProcessLocked removing on hold: " + app);
3557        mProcessesOnHold.remove(app);
3558
3559        checkTime(startTime, "startProcess: starting to update cpu stats");
3560        updateCpuStats();
3561        checkTime(startTime, "startProcess: done updating cpu stats");
3562
3563        try {
3564            try {
3565                final int userId = UserHandle.getUserId(app.uid);
3566                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3567            } catch (RemoteException e) {
3568                throw e.rethrowAsRuntimeException();
3569            }
3570
3571            int uid = app.uid;
3572            int[] gids = null;
3573            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3574            if (!app.isolated) {
3575                int[] permGids = null;
3576                try {
3577                    checkTime(startTime, "startProcess: getting gids from package manager");
3578                    final IPackageManager pm = AppGlobals.getPackageManager();
3579                    permGids = pm.getPackageGids(app.info.packageName,
3580                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3581                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3582                            MountServiceInternal.class);
3583                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3584                            app.info.packageName);
3585                } catch (RemoteException e) {
3586                    throw e.rethrowAsRuntimeException();
3587                }
3588
3589                /*
3590                 * Add shared application and profile GIDs so applications can share some
3591                 * resources like shared libraries and access user-wide resources
3592                 */
3593                if (ArrayUtils.isEmpty(permGids)) {
3594                    gids = new int[2];
3595                } else {
3596                    gids = new int[permGids.length + 2];
3597                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3598                }
3599                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3600                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3601            }
3602            checkTime(startTime, "startProcess: building args");
3603            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3604                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3605                        && mTopComponent != null
3606                        && app.processName.equals(mTopComponent.getPackageName())) {
3607                    uid = 0;
3608                }
3609                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3610                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3611                    uid = 0;
3612                }
3613            }
3614            int debugFlags = 0;
3615            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3616                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3617                // Also turn on CheckJNI for debuggable apps. It's quite
3618                // awkward to turn on otherwise.
3619                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3620            }
3621            // Run the app in safe mode if its manifest requests so or the
3622            // system is booted in safe mode.
3623            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3624                mSafeMode == true) {
3625                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3626            }
3627            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3628                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3629            }
3630            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3631            if ("true".equals(genDebugInfoProperty)) {
3632                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3633            }
3634            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3635                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3636            }
3637            if ("1".equals(SystemProperties.get("debug.assert"))) {
3638                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3639            }
3640            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3641                // Enable all debug flags required by the native debugger.
3642                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3643                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3644                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3645                mNativeDebuggingApp = null;
3646            }
3647
3648            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3649            if (requiredAbi == null) {
3650                requiredAbi = Build.SUPPORTED_ABIS[0];
3651            }
3652
3653            String instructionSet = null;
3654            if (app.info.primaryCpuAbi != null) {
3655                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3656            }
3657
3658            app.gids = gids;
3659            app.requiredAbi = requiredAbi;
3660            app.instructionSet = instructionSet;
3661
3662            // Start the process.  It will either succeed and return a result containing
3663            // the PID of the new process, or else throw a RuntimeException.
3664            boolean isActivityProcess = (entryPoint == null);
3665            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3666            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3667                    app.processName);
3668            checkTime(startTime, "startProcess: asking zygote to start proc");
3669            Process.ProcessStartResult startResult = Process.start(entryPoint,
3670                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3671                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3672                    app.info.dataDir, entryPointArgs);
3673            checkTime(startTime, "startProcess: returned from zygote!");
3674            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3675
3676            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3677            checkTime(startTime, "startProcess: done updating battery stats");
3678
3679            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3680                    UserHandle.getUserId(uid), startResult.pid, uid,
3681                    app.processName, hostingType,
3682                    hostingNameStr != null ? hostingNameStr : "");
3683
3684            try {
3685                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3686                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3687            } catch (RemoteException ex) {
3688                // Ignore
3689            }
3690
3691            if (app.persistent) {
3692                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3693            }
3694
3695            checkTime(startTime, "startProcess: building log message");
3696            StringBuilder buf = mStringBuilder;
3697            buf.setLength(0);
3698            buf.append("Start proc ");
3699            buf.append(startResult.pid);
3700            buf.append(':');
3701            buf.append(app.processName);
3702            buf.append('/');
3703            UserHandle.formatUid(buf, uid);
3704            if (!isActivityProcess) {
3705                buf.append(" [");
3706                buf.append(entryPoint);
3707                buf.append("]");
3708            }
3709            buf.append(" for ");
3710            buf.append(hostingType);
3711            if (hostingNameStr != null) {
3712                buf.append(" ");
3713                buf.append(hostingNameStr);
3714            }
3715            Slog.i(TAG, buf.toString());
3716            app.setPid(startResult.pid);
3717            app.usingWrapper = startResult.usingWrapper;
3718            app.removed = false;
3719            app.killed = false;
3720            app.killedByAm = false;
3721            checkTime(startTime, "startProcess: starting to update pids map");
3722            ProcessRecord oldApp;
3723            synchronized (mPidsSelfLocked) {
3724                oldApp = mPidsSelfLocked.get(startResult.pid);
3725            }
3726            // If there is already an app occupying that pid that hasn't been cleaned up
3727            if (oldApp != null && !app.isolated) {
3728                // Clean up anything relating to this pid first
3729                Slog.w(TAG, "Reusing pid " + startResult.pid
3730                        + " while app is still mapped to it");
3731                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3732                        true /*replacingPid*/);
3733            }
3734            synchronized (mPidsSelfLocked) {
3735                this.mPidsSelfLocked.put(startResult.pid, app);
3736                if (isActivityProcess) {
3737                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3738                    msg.obj = app;
3739                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3740                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3741                }
3742            }
3743            checkTime(startTime, "startProcess: done updating pids map");
3744        } catch (RuntimeException e) {
3745            Slog.e(TAG, "Failure starting process " + app.processName, e);
3746
3747            // Something went very wrong while trying to start this process; one
3748            // common case is when the package is frozen due to an active
3749            // upgrade. To recover, clean up any active bookkeeping related to
3750            // starting this process. (We already invoked this method once when
3751            // the package was initially frozen through KILL_APPLICATION_MSG, so
3752            // it doesn't hurt to use it again.)
3753            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3754                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3755        }
3756    }
3757
3758    void updateUsageStats(ActivityRecord component, boolean resumed) {
3759        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3760                "updateUsageStats: comp=" + component + "res=" + resumed);
3761        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3762        if (resumed) {
3763            if (mUsageStatsService != null) {
3764                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3765                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3766            }
3767            synchronized (stats) {
3768                stats.noteActivityResumedLocked(component.app.uid);
3769            }
3770        } else {
3771            if (mUsageStatsService != null) {
3772                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3773                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3774            }
3775            synchronized (stats) {
3776                stats.noteActivityPausedLocked(component.app.uid);
3777            }
3778        }
3779    }
3780
3781    Intent getHomeIntent() {
3782        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3783        intent.setComponent(mTopComponent);
3784        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3785        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3786            intent.addCategory(Intent.CATEGORY_HOME);
3787        }
3788        return intent;
3789    }
3790
3791    boolean startHomeActivityLocked(int userId, String reason) {
3792        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3793                && mTopAction == null) {
3794            // We are running in factory test mode, but unable to find
3795            // the factory test app, so just sit around displaying the
3796            // error message and don't try to start anything.
3797            return false;
3798        }
3799        Intent intent = getHomeIntent();
3800        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3801        if (aInfo != null) {
3802            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3803            // Don't do this if the home app is currently being
3804            // instrumented.
3805            aInfo = new ActivityInfo(aInfo);
3806            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3807            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3808                    aInfo.applicationInfo.uid, true);
3809            if (app == null || app.instrumentationClass == null) {
3810                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3811                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3812            }
3813        } else {
3814            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3815        }
3816
3817        return true;
3818    }
3819
3820    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3821        ActivityInfo ai = null;
3822        ComponentName comp = intent.getComponent();
3823        try {
3824            if (comp != null) {
3825                // Factory test.
3826                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3827            } else {
3828                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3829                        intent,
3830                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3831                        flags, userId);
3832
3833                if (info != null) {
3834                    ai = info.activityInfo;
3835                }
3836            }
3837        } catch (RemoteException e) {
3838            // ignore
3839        }
3840
3841        return ai;
3842    }
3843
3844    /**
3845     * Starts the "new version setup screen" if appropriate.
3846     */
3847    void startSetupActivityLocked() {
3848        // Only do this once per boot.
3849        if (mCheckedForSetup) {
3850            return;
3851        }
3852
3853        // We will show this screen if the current one is a different
3854        // version than the last one shown, and we are not running in
3855        // low-level factory test mode.
3856        final ContentResolver resolver = mContext.getContentResolver();
3857        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3858                Settings.Global.getInt(resolver,
3859                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3860            mCheckedForSetup = true;
3861
3862            // See if we should be showing the platform update setup UI.
3863            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3864            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3865                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3866            if (!ris.isEmpty()) {
3867                final ResolveInfo ri = ris.get(0);
3868                String vers = ri.activityInfo.metaData != null
3869                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3870                        : null;
3871                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3872                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3873                            Intent.METADATA_SETUP_VERSION);
3874                }
3875                String lastVers = Settings.Secure.getString(
3876                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3877                if (vers != null && !vers.equals(lastVers)) {
3878                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3879                    intent.setComponent(new ComponentName(
3880                            ri.activityInfo.packageName, ri.activityInfo.name));
3881                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3882                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3883                            null, 0, 0, 0, null, false, false, null, null, null);
3884                }
3885            }
3886        }
3887    }
3888
3889    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3890        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3891    }
3892
3893    void enforceNotIsolatedCaller(String caller) {
3894        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3895            throw new SecurityException("Isolated process not allowed to call " + caller);
3896        }
3897    }
3898
3899    void enforceShellRestriction(String restriction, int userHandle) {
3900        if (Binder.getCallingUid() == Process.SHELL_UID) {
3901            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3902                throw new SecurityException("Shell does not have permission to access user "
3903                        + userHandle);
3904            }
3905        }
3906    }
3907
3908    @Override
3909    public int getFrontActivityScreenCompatMode() {
3910        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3911        synchronized (this) {
3912            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3913        }
3914    }
3915
3916    @Override
3917    public void setFrontActivityScreenCompatMode(int mode) {
3918        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3919                "setFrontActivityScreenCompatMode");
3920        synchronized (this) {
3921            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3922        }
3923    }
3924
3925    @Override
3926    public int getPackageScreenCompatMode(String packageName) {
3927        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3928        synchronized (this) {
3929            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3930        }
3931    }
3932
3933    @Override
3934    public void setPackageScreenCompatMode(String packageName, int mode) {
3935        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3936                "setPackageScreenCompatMode");
3937        synchronized (this) {
3938            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3939        }
3940    }
3941
3942    @Override
3943    public boolean getPackageAskScreenCompat(String packageName) {
3944        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3945        synchronized (this) {
3946            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3947        }
3948    }
3949
3950    @Override
3951    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3952        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3953                "setPackageAskScreenCompat");
3954        synchronized (this) {
3955            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3956        }
3957    }
3958
3959    private boolean hasUsageStatsPermission(String callingPackage) {
3960        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3961                Binder.getCallingUid(), callingPackage);
3962        if (mode == AppOpsManager.MODE_DEFAULT) {
3963            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3964                    == PackageManager.PERMISSION_GRANTED;
3965        }
3966        return mode == AppOpsManager.MODE_ALLOWED;
3967    }
3968
3969    @Override
3970    public int getPackageProcessState(String packageName, String callingPackage) {
3971        if (!hasUsageStatsPermission(callingPackage)) {
3972            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
3973                    "getPackageProcessState");
3974        }
3975
3976        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3977        synchronized (this) {
3978            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3979                final ProcessRecord proc = mLruProcesses.get(i);
3980                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3981                        || procState > proc.setProcState) {
3982                    if (proc.pkgList.containsKey(packageName)) {
3983                        procState = proc.setProcState;
3984                        break;
3985                    }
3986                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
3987                        procState = proc.setProcState;
3988                    }
3989                }
3990            }
3991        }
3992        return procState;
3993    }
3994
3995    @Override
3996    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
3997            throws RemoteException {
3998        synchronized (this) {
3999            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4000            if (app == null) {
4001                throw new IllegalArgumentException("Unknown process: " + process);
4002            }
4003            if (app.thread == null) {
4004                throw new IllegalArgumentException("Process has no app thread");
4005            }
4006            if (app.trimMemoryLevel >= level) {
4007                throw new IllegalArgumentException(
4008                        "Unable to set a higher trim level than current level");
4009            }
4010            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4011                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4012                throw new IllegalArgumentException("Unable to set a background trim level "
4013                    + "on a foreground process");
4014            }
4015            app.thread.scheduleTrimMemory(level);
4016            app.trimMemoryLevel = level;
4017            return true;
4018        }
4019    }
4020
4021    private void dispatchProcessesChanged() {
4022        int N;
4023        synchronized (this) {
4024            N = mPendingProcessChanges.size();
4025            if (mActiveProcessChanges.length < N) {
4026                mActiveProcessChanges = new ProcessChangeItem[N];
4027            }
4028            mPendingProcessChanges.toArray(mActiveProcessChanges);
4029            mPendingProcessChanges.clear();
4030            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4031                    "*** Delivering " + N + " process changes");
4032        }
4033
4034        int i = mProcessObservers.beginBroadcast();
4035        while (i > 0) {
4036            i--;
4037            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4038            if (observer != null) {
4039                try {
4040                    for (int j=0; j<N; j++) {
4041                        ProcessChangeItem item = mActiveProcessChanges[j];
4042                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4043                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4044                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4045                                    + item.uid + ": " + item.foregroundActivities);
4046                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4047                                    item.foregroundActivities);
4048                        }
4049                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4050                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4051                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4052                                    + ": " + item.processState);
4053                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4054                        }
4055                    }
4056                } catch (RemoteException e) {
4057                }
4058            }
4059        }
4060        mProcessObservers.finishBroadcast();
4061
4062        synchronized (this) {
4063            for (int j=0; j<N; j++) {
4064                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4065            }
4066        }
4067    }
4068
4069    private void dispatchProcessDied(int pid, int uid) {
4070        int i = mProcessObservers.beginBroadcast();
4071        while (i > 0) {
4072            i--;
4073            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4074            if (observer != null) {
4075                try {
4076                    observer.onProcessDied(pid, uid);
4077                } catch (RemoteException e) {
4078                }
4079            }
4080        }
4081        mProcessObservers.finishBroadcast();
4082    }
4083
4084    private void dispatchUidsChanged() {
4085        int N;
4086        synchronized (this) {
4087            N = mPendingUidChanges.size();
4088            if (mActiveUidChanges.length < N) {
4089                mActiveUidChanges = new UidRecord.ChangeItem[N];
4090            }
4091            for (int i=0; i<N; i++) {
4092                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4093                mActiveUidChanges[i] = change;
4094                if (change.uidRecord != null) {
4095                    change.uidRecord.pendingChange = null;
4096                    change.uidRecord = null;
4097                }
4098            }
4099            mPendingUidChanges.clear();
4100            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4101                    "*** Delivering " + N + " uid changes");
4102        }
4103
4104        int i = mUidObservers.beginBroadcast();
4105        while (i > 0) {
4106            i--;
4107            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4108            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4109            if (observer != null) {
4110                try {
4111                    for (int j=0; j<N; j++) {
4112                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4113                        final int change = item.change;
4114                        UidRecord validateUid = null;
4115                        if (VALIDATE_UID_STATES && i == 0) {
4116                            validateUid = mValidateUids.get(item.uid);
4117                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4118                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4119                                validateUid = new UidRecord(item.uid);
4120                                mValidateUids.put(item.uid, validateUid);
4121                            }
4122                        }
4123                        if (change == UidRecord.CHANGE_IDLE
4124                                || change == UidRecord.CHANGE_GONE_IDLE) {
4125                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4126                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4127                                        "UID idle uid=" + item.uid);
4128                                observer.onUidIdle(item.uid);
4129                            }
4130                            if (VALIDATE_UID_STATES && i == 0) {
4131                                if (validateUid != null) {
4132                                    validateUid.idle = true;
4133                                }
4134                            }
4135                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4136                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4137                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4138                                        "UID active uid=" + item.uid);
4139                                observer.onUidActive(item.uid);
4140                            }
4141                            if (VALIDATE_UID_STATES && i == 0) {
4142                                validateUid.idle = false;
4143                            }
4144                        }
4145                        if (change == UidRecord.CHANGE_GONE
4146                                || change == UidRecord.CHANGE_GONE_IDLE) {
4147                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4148                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4149                                        "UID gone uid=" + item.uid);
4150                                observer.onUidGone(item.uid);
4151                            }
4152                            if (VALIDATE_UID_STATES && i == 0) {
4153                                if (validateUid != null) {
4154                                    mValidateUids.remove(item.uid);
4155                                }
4156                            }
4157                        } else {
4158                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4159                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4160                                        "UID CHANGED uid=" + item.uid
4161                                                + ": " + item.processState);
4162                                observer.onUidStateChanged(item.uid, item.processState);
4163                            }
4164                            if (VALIDATE_UID_STATES && i == 0) {
4165                                validateUid.curProcState = validateUid.setProcState
4166                                        = item.processState;
4167                            }
4168                        }
4169                    }
4170                } catch (RemoteException e) {
4171                }
4172            }
4173        }
4174        mUidObservers.finishBroadcast();
4175
4176        synchronized (this) {
4177            for (int j=0; j<N; j++) {
4178                mAvailUidChanges.add(mActiveUidChanges[j]);
4179            }
4180        }
4181    }
4182
4183    @Override
4184    public final int startActivity(IApplicationThread caller, String callingPackage,
4185            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4186            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4187        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4188                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4189                UserHandle.getCallingUserId());
4190    }
4191
4192    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4193        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4194        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4195                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4196                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4197
4198        // TODO: Switch to user app stacks here.
4199        String mimeType = intent.getType();
4200        final Uri data = intent.getData();
4201        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4202            mimeType = getProviderMimeType(data, userId);
4203        }
4204        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4205
4206        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4207        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4208                null, 0, 0, null, null, null, null, false, userId, container, null);
4209    }
4210
4211    @Override
4212    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4213            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4214            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4215        enforceNotIsolatedCaller("startActivity");
4216        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4217                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4218        // TODO: Switch to user app stacks here.
4219        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4220                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4221                profilerInfo, null, null, bOptions, false, userId, null, null);
4222    }
4223
4224    @Override
4225    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4226            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4227            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4228            int userId) {
4229
4230        // This is very dangerous -- it allows you to perform a start activity (including
4231        // permission grants) as any app that may launch one of your own activities.  So
4232        // we will only allow this to be done from activities that are part of the core framework,
4233        // and then only when they are running as the system.
4234        final ActivityRecord sourceRecord;
4235        final int targetUid;
4236        final String targetPackage;
4237        synchronized (this) {
4238            if (resultTo == null) {
4239                throw new SecurityException("Must be called from an activity");
4240            }
4241            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4242            if (sourceRecord == null) {
4243                throw new SecurityException("Called with bad activity token: " + resultTo);
4244            }
4245            if (!sourceRecord.info.packageName.equals("android")) {
4246                throw new SecurityException(
4247                        "Must be called from an activity that is declared in the android package");
4248            }
4249            if (sourceRecord.app == null) {
4250                throw new SecurityException("Called without a process attached to activity");
4251            }
4252            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4253                // This is still okay, as long as this activity is running under the
4254                // uid of the original calling activity.
4255                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4256                    throw new SecurityException(
4257                            "Calling activity in uid " + sourceRecord.app.uid
4258                                    + " must be system uid or original calling uid "
4259                                    + sourceRecord.launchedFromUid);
4260                }
4261            }
4262            if (ignoreTargetSecurity) {
4263                if (intent.getComponent() == null) {
4264                    throw new SecurityException(
4265                            "Component must be specified with ignoreTargetSecurity");
4266                }
4267                if (intent.getSelector() != null) {
4268                    throw new SecurityException(
4269                            "Selector not allowed with ignoreTargetSecurity");
4270                }
4271            }
4272            targetUid = sourceRecord.launchedFromUid;
4273            targetPackage = sourceRecord.launchedFromPackage;
4274        }
4275
4276        if (userId == UserHandle.USER_NULL) {
4277            userId = UserHandle.getUserId(sourceRecord.app.uid);
4278        }
4279
4280        // TODO: Switch to user app stacks here.
4281        try {
4282            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4283                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4284                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4285            return ret;
4286        } catch (SecurityException e) {
4287            // XXX need to figure out how to propagate to original app.
4288            // A SecurityException here is generally actually a fault of the original
4289            // calling activity (such as a fairly granting permissions), so propagate it
4290            // back to them.
4291            /*
4292            StringBuilder msg = new StringBuilder();
4293            msg.append("While launching");
4294            msg.append(intent.toString());
4295            msg.append(": ");
4296            msg.append(e.getMessage());
4297            */
4298            throw e;
4299        }
4300    }
4301
4302    @Override
4303    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4304            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4305            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4306        enforceNotIsolatedCaller("startActivityAndWait");
4307        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4308                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4309        WaitResult res = new WaitResult();
4310        // TODO: Switch to user app stacks here.
4311        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4312                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4313                bOptions, false, userId, null, null);
4314        return res;
4315    }
4316
4317    @Override
4318    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4319            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4320            int startFlags, Configuration config, Bundle bOptions, int userId) {
4321        enforceNotIsolatedCaller("startActivityWithConfig");
4322        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4323                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4324        // TODO: Switch to user app stacks here.
4325        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4326                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4327                null, null, config, bOptions, false, userId, null, null);
4328        return ret;
4329    }
4330
4331    @Override
4332    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4333            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4334            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4335            throws TransactionTooLargeException {
4336        enforceNotIsolatedCaller("startActivityIntentSender");
4337        // Refuse possible leaked file descriptors
4338        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4339            throw new IllegalArgumentException("File descriptors passed in Intent");
4340        }
4341
4342        IIntentSender sender = intent.getTarget();
4343        if (!(sender instanceof PendingIntentRecord)) {
4344            throw new IllegalArgumentException("Bad PendingIntent object");
4345        }
4346
4347        PendingIntentRecord pir = (PendingIntentRecord)sender;
4348
4349        synchronized (this) {
4350            // If this is coming from the currently resumed activity, it is
4351            // effectively saying that app switches are allowed at this point.
4352            final ActivityStack stack = getFocusedStack();
4353            if (stack.mResumedActivity != null &&
4354                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4355                mAppSwitchesAllowedTime = 0;
4356            }
4357        }
4358        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4359                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4360        return ret;
4361    }
4362
4363    @Override
4364    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4365            Intent intent, String resolvedType, IVoiceInteractionSession session,
4366            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4367            Bundle bOptions, int userId) {
4368        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4369                != PackageManager.PERMISSION_GRANTED) {
4370            String msg = "Permission Denial: startVoiceActivity() from pid="
4371                    + Binder.getCallingPid()
4372                    + ", uid=" + Binder.getCallingUid()
4373                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4374            Slog.w(TAG, msg);
4375            throw new SecurityException(msg);
4376        }
4377        if (session == null || interactor == null) {
4378            throw new NullPointerException("null session or interactor");
4379        }
4380        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4381                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4382        // TODO: Switch to user app stacks here.
4383        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4384                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4385                null, bOptions, false, userId, null, null);
4386    }
4387
4388    @Override
4389    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4390            throws RemoteException {
4391        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4392        synchronized (this) {
4393            ActivityRecord activity = getFocusedStack().topActivity();
4394            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4395                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4396            }
4397            if (mRunningVoice != null || activity.task.voiceSession != null
4398                    || activity.voiceSession != null) {
4399                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4400                return;
4401            }
4402            if (activity.pendingVoiceInteractionStart) {
4403                Slog.w(TAG, "Pending start of voice interaction already.");
4404                return;
4405            }
4406            activity.pendingVoiceInteractionStart = true;
4407        }
4408        LocalServices.getService(VoiceInteractionManagerInternal.class)
4409                .startLocalVoiceInteraction(callingActivity, options);
4410    }
4411
4412    @Override
4413    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4414        LocalServices.getService(VoiceInteractionManagerInternal.class)
4415                .stopLocalVoiceInteraction(callingActivity);
4416    }
4417
4418    @Override
4419    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4420        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4421                .supportsLocalVoiceInteraction();
4422    }
4423
4424    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4425            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4426        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4427        if (activityToCallback == null) return;
4428        activityToCallback.setVoiceSessionLocked(voiceSession);
4429
4430        // Inform the activity
4431        try {
4432            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4433                    voiceInteractor);
4434            long token = Binder.clearCallingIdentity();
4435            try {
4436                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4437            } finally {
4438                Binder.restoreCallingIdentity(token);
4439            }
4440            // TODO: VI Should we cache the activity so that it's easier to find later
4441            // rather than scan through all the stacks and activities?
4442        } catch (RemoteException re) {
4443            activityToCallback.clearVoiceSessionLocked();
4444            // TODO: VI Should this terminate the voice session?
4445        }
4446    }
4447
4448    @Override
4449    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4450        synchronized (this) {
4451            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4452                if (keepAwake) {
4453                    mVoiceWakeLock.acquire();
4454                } else {
4455                    mVoiceWakeLock.release();
4456                }
4457            }
4458        }
4459    }
4460
4461    @Override
4462    public boolean startNextMatchingActivity(IBinder callingActivity,
4463            Intent intent, Bundle bOptions) {
4464        // Refuse possible leaked file descriptors
4465        if (intent != null && intent.hasFileDescriptors() == true) {
4466            throw new IllegalArgumentException("File descriptors passed in Intent");
4467        }
4468        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4469
4470        synchronized (this) {
4471            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4472            if (r == null) {
4473                ActivityOptions.abort(options);
4474                return false;
4475            }
4476            if (r.app == null || r.app.thread == null) {
4477                // The caller is not running...  d'oh!
4478                ActivityOptions.abort(options);
4479                return false;
4480            }
4481            intent = new Intent(intent);
4482            // The caller is not allowed to change the data.
4483            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4484            // And we are resetting to find the next component...
4485            intent.setComponent(null);
4486
4487            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4488
4489            ActivityInfo aInfo = null;
4490            try {
4491                List<ResolveInfo> resolves =
4492                    AppGlobals.getPackageManager().queryIntentActivities(
4493                            intent, r.resolvedType,
4494                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4495                            UserHandle.getCallingUserId()).getList();
4496
4497                // Look for the original activity in the list...
4498                final int N = resolves != null ? resolves.size() : 0;
4499                for (int i=0; i<N; i++) {
4500                    ResolveInfo rInfo = resolves.get(i);
4501                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4502                            && rInfo.activityInfo.name.equals(r.info.name)) {
4503                        // We found the current one...  the next matching is
4504                        // after it.
4505                        i++;
4506                        if (i<N) {
4507                            aInfo = resolves.get(i).activityInfo;
4508                        }
4509                        if (debug) {
4510                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4511                                    + "/" + r.info.name);
4512                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4513                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4514                        }
4515                        break;
4516                    }
4517                }
4518            } catch (RemoteException e) {
4519            }
4520
4521            if (aInfo == null) {
4522                // Nobody who is next!
4523                ActivityOptions.abort(options);
4524                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4525                return false;
4526            }
4527
4528            intent.setComponent(new ComponentName(
4529                    aInfo.applicationInfo.packageName, aInfo.name));
4530            intent.setFlags(intent.getFlags()&~(
4531                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4532                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4533                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4534                    Intent.FLAG_ACTIVITY_NEW_TASK));
4535
4536            // Okay now we need to start the new activity, replacing the
4537            // currently running activity.  This is a little tricky because
4538            // we want to start the new one as if the current one is finished,
4539            // but not finish the current one first so that there is no flicker.
4540            // And thus...
4541            final boolean wasFinishing = r.finishing;
4542            r.finishing = true;
4543
4544            // Propagate reply information over to the new activity.
4545            final ActivityRecord resultTo = r.resultTo;
4546            final String resultWho = r.resultWho;
4547            final int requestCode = r.requestCode;
4548            r.resultTo = null;
4549            if (resultTo != null) {
4550                resultTo.removeResultsLocked(r, resultWho, requestCode);
4551            }
4552
4553            final long origId = Binder.clearCallingIdentity();
4554            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4555                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4556                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4557                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4558                    false, false, null, null, null);
4559            Binder.restoreCallingIdentity(origId);
4560
4561            r.finishing = wasFinishing;
4562            if (res != ActivityManager.START_SUCCESS) {
4563                return false;
4564            }
4565            return true;
4566        }
4567    }
4568
4569    @Override
4570    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4571        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4572            String msg = "Permission Denial: startActivityFromRecents called without " +
4573                    START_TASKS_FROM_RECENTS;
4574            Slog.w(TAG, msg);
4575            throw new SecurityException(msg);
4576        }
4577        final long origId = Binder.clearCallingIdentity();
4578        try {
4579            synchronized (this) {
4580                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4581            }
4582        } finally {
4583            Binder.restoreCallingIdentity(origId);
4584        }
4585    }
4586
4587    final int startActivityInPackage(int uid, String callingPackage,
4588            Intent intent, String resolvedType, IBinder resultTo,
4589            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4590            IActivityContainer container, TaskRecord inTask) {
4591
4592        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4593                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4594
4595        // TODO: Switch to user app stacks here.
4596        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4597                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4598                null, null, null, bOptions, false, userId, container, inTask);
4599        return ret;
4600    }
4601
4602    @Override
4603    public final int startActivities(IApplicationThread caller, String callingPackage,
4604            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4605            int userId) {
4606        enforceNotIsolatedCaller("startActivities");
4607        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4608                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4609        // TODO: Switch to user app stacks here.
4610        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4611                resolvedTypes, resultTo, bOptions, userId);
4612        return ret;
4613    }
4614
4615    final int startActivitiesInPackage(int uid, String callingPackage,
4616            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4617            Bundle bOptions, int userId) {
4618
4619        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4620                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4621        // TODO: Switch to user app stacks here.
4622        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4623                resultTo, bOptions, userId);
4624        return ret;
4625    }
4626
4627    @Override
4628    public void reportActivityFullyDrawn(IBinder token) {
4629        synchronized (this) {
4630            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4631            if (r == null) {
4632                return;
4633            }
4634            r.reportFullyDrawnLocked();
4635        }
4636    }
4637
4638    @Override
4639    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4640        synchronized (this) {
4641            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4642            if (r == null) {
4643                return;
4644            }
4645            final long origId = Binder.clearCallingIdentity();
4646            try {
4647                r.setRequestedOrientation(requestedOrientation);
4648            } finally {
4649                Binder.restoreCallingIdentity(origId);
4650            }
4651        }
4652    }
4653
4654    @Override
4655    public int getRequestedOrientation(IBinder token) {
4656        synchronized (this) {
4657            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4658            if (r == null) {
4659                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4660            }
4661            return mWindowManager.getAppOrientation(r.appToken);
4662        }
4663    }
4664
4665    @Override
4666    public final void requestActivityRelaunch(IBinder token) {
4667        synchronized(this) {
4668            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4669            if (r == null) {
4670                return;
4671            }
4672            final long origId = Binder.clearCallingIdentity();
4673            try {
4674                r.forceNewConfig = true;
4675                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4676                        false /* preserveWindow */);
4677            } finally {
4678                Binder.restoreCallingIdentity(origId);
4679            }
4680        }
4681    }
4682
4683    /**
4684     * This is the internal entry point for handling Activity.finish().
4685     *
4686     * @param token The Binder token referencing the Activity we want to finish.
4687     * @param resultCode Result code, if any, from this Activity.
4688     * @param resultData Result data (Intent), if any, from this Activity.
4689     * @param finishTask Whether to finish the task associated with this Activity.
4690     *
4691     * @return Returns true if the activity successfully finished, or false if it is still running.
4692     */
4693    @Override
4694    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4695            int finishTask) {
4696        // Refuse possible leaked file descriptors
4697        if (resultData != null && resultData.hasFileDescriptors() == true) {
4698            throw new IllegalArgumentException("File descriptors passed in Intent");
4699        }
4700
4701        synchronized(this) {
4702            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4703            if (r == null) {
4704                return true;
4705            }
4706            // Keep track of the root activity of the task before we finish it
4707            TaskRecord tr = r.task;
4708            ActivityRecord rootR = tr.getRootActivity();
4709            if (rootR == null) {
4710                Slog.w(TAG, "Finishing task with all activities already finished");
4711            }
4712            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4713            // finish.
4714            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4715                    mStackSupervisor.isLastLockedTask(tr)) {
4716                Slog.i(TAG, "Not finishing task in lock task mode");
4717                mStackSupervisor.showLockTaskToast();
4718                return false;
4719            }
4720            if (mController != null) {
4721                // Find the first activity that is not finishing.
4722                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4723                if (next != null) {
4724                    // ask watcher if this is allowed
4725                    boolean resumeOK = true;
4726                    try {
4727                        resumeOK = mController.activityResuming(next.packageName);
4728                    } catch (RemoteException e) {
4729                        mController = null;
4730                        Watchdog.getInstance().setActivityController(null);
4731                    }
4732
4733                    if (!resumeOK) {
4734                        Slog.i(TAG, "Not finishing activity because controller resumed");
4735                        return false;
4736                    }
4737                }
4738            }
4739            final long origId = Binder.clearCallingIdentity();
4740            try {
4741                boolean res;
4742                final boolean finishWithRootActivity =
4743                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4744                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4745                        || (finishWithRootActivity && r == rootR)) {
4746                    // If requested, remove the task that is associated to this activity only if it
4747                    // was the root activity in the task. The result code and data is ignored
4748                    // because we don't support returning them across task boundaries. Also, to
4749                    // keep backwards compatibility we remove the task from recents when finishing
4750                    // task with root activity.
4751                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4752                    if (!res) {
4753                        Slog.i(TAG, "Removing task failed to finish activity");
4754                    }
4755                } else {
4756                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4757                            resultData, "app-request", true);
4758                    if (!res) {
4759                        Slog.i(TAG, "Failed to finish by app-request");
4760                    }
4761                }
4762                return res;
4763            } finally {
4764                Binder.restoreCallingIdentity(origId);
4765            }
4766        }
4767    }
4768
4769    @Override
4770    public final void finishHeavyWeightApp() {
4771        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4772                != PackageManager.PERMISSION_GRANTED) {
4773            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4774                    + Binder.getCallingPid()
4775                    + ", uid=" + Binder.getCallingUid()
4776                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4777            Slog.w(TAG, msg);
4778            throw new SecurityException(msg);
4779        }
4780
4781        synchronized(this) {
4782            if (mHeavyWeightProcess == null) {
4783                return;
4784            }
4785
4786            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4787            for (int i = 0; i < activities.size(); i++) {
4788                ActivityRecord r = activities.get(i);
4789                if (!r.finishing && r.isInStackLocked()) {
4790                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4791                            null, "finish-heavy", true);
4792                }
4793            }
4794
4795            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4796                    mHeavyWeightProcess.userId, 0));
4797            mHeavyWeightProcess = null;
4798        }
4799    }
4800
4801    @Override
4802    public void crashApplication(int uid, int initialPid, String packageName,
4803            String message) {
4804        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4805                != PackageManager.PERMISSION_GRANTED) {
4806            String msg = "Permission Denial: crashApplication() from pid="
4807                    + Binder.getCallingPid()
4808                    + ", uid=" + Binder.getCallingUid()
4809                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4810            Slog.w(TAG, msg);
4811            throw new SecurityException(msg);
4812        }
4813
4814        synchronized(this) {
4815            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4816        }
4817    }
4818
4819    @Override
4820    public final void finishSubActivity(IBinder token, String resultWho,
4821            int requestCode) {
4822        synchronized(this) {
4823            final long origId = Binder.clearCallingIdentity();
4824            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4825            if (r != null) {
4826                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4827            }
4828            Binder.restoreCallingIdentity(origId);
4829        }
4830    }
4831
4832    @Override
4833    public boolean finishActivityAffinity(IBinder token) {
4834        synchronized(this) {
4835            final long origId = Binder.clearCallingIdentity();
4836            try {
4837                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4838                if (r == null) {
4839                    return false;
4840                }
4841
4842                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4843                // can finish.
4844                final TaskRecord task = r.task;
4845                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4846                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4847                    mStackSupervisor.showLockTaskToast();
4848                    return false;
4849                }
4850                return task.getStack().finishActivityAffinityLocked(r);
4851            } finally {
4852                Binder.restoreCallingIdentity(origId);
4853            }
4854        }
4855    }
4856
4857    @Override
4858    public void finishVoiceTask(IVoiceInteractionSession session) {
4859        synchronized (this) {
4860            final long origId = Binder.clearCallingIdentity();
4861            try {
4862                // TODO: VI Consider treating local voice interactions and voice tasks
4863                // differently here
4864                mStackSupervisor.finishVoiceTask(session);
4865            } finally {
4866                Binder.restoreCallingIdentity(origId);
4867            }
4868        }
4869
4870    }
4871
4872    @Override
4873    public boolean releaseActivityInstance(IBinder token) {
4874        synchronized(this) {
4875            final long origId = Binder.clearCallingIdentity();
4876            try {
4877                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4878                if (r == null) {
4879                    return false;
4880                }
4881                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4882            } finally {
4883                Binder.restoreCallingIdentity(origId);
4884            }
4885        }
4886    }
4887
4888    @Override
4889    public void releaseSomeActivities(IApplicationThread appInt) {
4890        synchronized(this) {
4891            final long origId = Binder.clearCallingIdentity();
4892            try {
4893                ProcessRecord app = getRecordForAppLocked(appInt);
4894                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4895            } finally {
4896                Binder.restoreCallingIdentity(origId);
4897            }
4898        }
4899    }
4900
4901    @Override
4902    public boolean willActivityBeVisible(IBinder token) {
4903        synchronized(this) {
4904            ActivityStack stack = ActivityRecord.getStackLocked(token);
4905            if (stack != null) {
4906                return stack.willActivityBeVisibleLocked(token);
4907            }
4908            return false;
4909        }
4910    }
4911
4912    @Override
4913    public void overridePendingTransition(IBinder token, String packageName,
4914            int enterAnim, int exitAnim) {
4915        synchronized(this) {
4916            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4917            if (self == null) {
4918                return;
4919            }
4920
4921            final long origId = Binder.clearCallingIdentity();
4922
4923            if (self.state == ActivityState.RESUMED
4924                    || self.state == ActivityState.PAUSING) {
4925                mWindowManager.overridePendingAppTransition(packageName,
4926                        enterAnim, exitAnim, null);
4927            }
4928
4929            Binder.restoreCallingIdentity(origId);
4930        }
4931    }
4932
4933    /**
4934     * Main function for removing an existing process from the activity manager
4935     * as a result of that process going away.  Clears out all connections
4936     * to the process.
4937     */
4938    private final void handleAppDiedLocked(ProcessRecord app,
4939            boolean restarting, boolean allowRestart) {
4940        int pid = app.pid;
4941        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4942                false /*replacingPid*/);
4943        if (!kept && !restarting) {
4944            removeLruProcessLocked(app);
4945            if (pid > 0) {
4946                ProcessList.remove(pid);
4947            }
4948        }
4949
4950        if (mProfileProc == app) {
4951            clearProfilerLocked();
4952        }
4953
4954        // Remove this application's activities from active lists.
4955        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4956
4957        app.activities.clear();
4958
4959        if (app.instrumentationClass != null) {
4960            Slog.w(TAG, "Crash of app " + app.processName
4961                  + " running instrumentation " + app.instrumentationClass);
4962            Bundle info = new Bundle();
4963            info.putString("shortMsg", "Process crashed.");
4964            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4965        }
4966
4967        mWindowManager.deferSurfaceLayout();
4968        try {
4969            if (!restarting && hasVisibleActivities
4970                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4971                // If there was nothing to resume, and we are not already restarting this process, but
4972                // there is a visible activity that is hosted by the process...  then make sure all
4973                // visible activities are running, taking care of restarting this process.
4974                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4975            }
4976        } finally {
4977            mWindowManager.continueSurfaceLayout();
4978        }
4979    }
4980
4981    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4982        IBinder threadBinder = thread.asBinder();
4983        // Find the application record.
4984        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4985            ProcessRecord rec = mLruProcesses.get(i);
4986            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4987                return i;
4988            }
4989        }
4990        return -1;
4991    }
4992
4993    final ProcessRecord getRecordForAppLocked(
4994            IApplicationThread thread) {
4995        if (thread == null) {
4996            return null;
4997        }
4998
4999        int appIndex = getLRURecordIndexForAppLocked(thread);
5000        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5001    }
5002
5003    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5004        // If there are no longer any background processes running,
5005        // and the app that died was not running instrumentation,
5006        // then tell everyone we are now low on memory.
5007        boolean haveBg = false;
5008        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5009            ProcessRecord rec = mLruProcesses.get(i);
5010            if (rec.thread != null
5011                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5012                haveBg = true;
5013                break;
5014            }
5015        }
5016
5017        if (!haveBg) {
5018            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5019            if (doReport) {
5020                long now = SystemClock.uptimeMillis();
5021                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5022                    doReport = false;
5023                } else {
5024                    mLastMemUsageReportTime = now;
5025                }
5026            }
5027            final ArrayList<ProcessMemInfo> memInfos
5028                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5029            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5030            long now = SystemClock.uptimeMillis();
5031            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5032                ProcessRecord rec = mLruProcesses.get(i);
5033                if (rec == dyingProc || rec.thread == null) {
5034                    continue;
5035                }
5036                if (doReport) {
5037                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5038                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5039                }
5040                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5041                    // The low memory report is overriding any current
5042                    // state for a GC request.  Make sure to do
5043                    // heavy/important/visible/foreground processes first.
5044                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5045                        rec.lastRequestedGc = 0;
5046                    } else {
5047                        rec.lastRequestedGc = rec.lastLowMemory;
5048                    }
5049                    rec.reportLowMemory = true;
5050                    rec.lastLowMemory = now;
5051                    mProcessesToGc.remove(rec);
5052                    addProcessToGcListLocked(rec);
5053                }
5054            }
5055            if (doReport) {
5056                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5057                mHandler.sendMessage(msg);
5058            }
5059            scheduleAppGcsLocked();
5060        }
5061    }
5062
5063    final void appDiedLocked(ProcessRecord app) {
5064       appDiedLocked(app, app.pid, app.thread, false);
5065    }
5066
5067    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5068            boolean fromBinderDied) {
5069        // First check if this ProcessRecord is actually active for the pid.
5070        synchronized (mPidsSelfLocked) {
5071            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5072            if (curProc != app) {
5073                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5074                return;
5075            }
5076        }
5077
5078        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5079        synchronized (stats) {
5080            stats.noteProcessDiedLocked(app.info.uid, pid);
5081        }
5082
5083        if (!app.killed) {
5084            if (!fromBinderDied) {
5085                Process.killProcessQuiet(pid);
5086            }
5087            killProcessGroup(app.uid, pid);
5088            app.killed = true;
5089        }
5090
5091        // Clean up already done if the process has been re-started.
5092        if (app.pid == pid && app.thread != null &&
5093                app.thread.asBinder() == thread.asBinder()) {
5094            boolean doLowMem = app.instrumentationClass == null;
5095            boolean doOomAdj = doLowMem;
5096            if (!app.killedByAm) {
5097                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5098                        + ") has died");
5099                mAllowLowerMemLevel = true;
5100            } else {
5101                // Note that we always want to do oom adj to update our state with the
5102                // new number of procs.
5103                mAllowLowerMemLevel = false;
5104                doLowMem = false;
5105            }
5106            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5107            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5108                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5109            handleAppDiedLocked(app, false, true);
5110
5111            if (doOomAdj) {
5112                updateOomAdjLocked();
5113            }
5114            if (doLowMem) {
5115                doLowMemReportIfNeededLocked(app);
5116            }
5117        } else if (app.pid != pid) {
5118            // A new process has already been started.
5119            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5120                    + ") has died and restarted (pid " + app.pid + ").");
5121            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5122        } else if (DEBUG_PROCESSES) {
5123            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5124                    + thread.asBinder());
5125        }
5126    }
5127
5128    /**
5129     * If a stack trace dump file is configured, dump process stack traces.
5130     * @param clearTraces causes the dump file to be erased prior to the new
5131     *    traces being written, if true; when false, the new traces will be
5132     *    appended to any existing file content.
5133     * @param firstPids of dalvik VM processes to dump stack traces for first
5134     * @param lastPids of dalvik VM processes to dump stack traces for last
5135     * @param nativeProcs optional list of native process names to dump stack crawls
5136     * @return file containing stack traces, or null if no dump file is configured
5137     */
5138    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5139            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5140        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5141        if (tracesPath == null || tracesPath.length() == 0) {
5142            return null;
5143        }
5144
5145        File tracesFile = new File(tracesPath);
5146        try {
5147            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5148            tracesFile.createNewFile();
5149            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5150        } catch (IOException e) {
5151            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5152            return null;
5153        }
5154
5155        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5156        return tracesFile;
5157    }
5158
5159    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5160            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5161        // Use a FileObserver to detect when traces finish writing.
5162        // The order of traces is considered important to maintain for legibility.
5163        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5164            @Override
5165            public synchronized void onEvent(int event, String path) { notify(); }
5166        };
5167
5168        try {
5169            observer.startWatching();
5170
5171            // First collect all of the stacks of the most important pids.
5172            if (firstPids != null) {
5173                try {
5174                    int num = firstPids.size();
5175                    for (int i = 0; i < num; i++) {
5176                        synchronized (observer) {
5177                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5178                                    + firstPids.get(i));
5179                            final long sime = SystemClock.elapsedRealtime();
5180                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5181                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5182                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5183                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5184                        }
5185                    }
5186                } catch (InterruptedException e) {
5187                    Slog.wtf(TAG, e);
5188                }
5189            }
5190
5191            // Next collect the stacks of the native pids
5192            if (nativeProcs != null) {
5193                int[] pids = Process.getPidsForCommands(nativeProcs);
5194                if (pids != null) {
5195                    for (int pid : pids) {
5196                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5197                        final long sime = SystemClock.elapsedRealtime();
5198                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5199                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5200                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5201                    }
5202                }
5203            }
5204
5205            // Lastly, measure CPU usage.
5206            if (processCpuTracker != null) {
5207                processCpuTracker.init();
5208                System.gc();
5209                processCpuTracker.update();
5210                try {
5211                    synchronized (processCpuTracker) {
5212                        processCpuTracker.wait(500); // measure over 1/2 second.
5213                    }
5214                } catch (InterruptedException e) {
5215                }
5216                processCpuTracker.update();
5217
5218                // We'll take the stack crawls of just the top apps using CPU.
5219                final int N = processCpuTracker.countWorkingStats();
5220                int numProcs = 0;
5221                for (int i=0; i<N && numProcs<5; i++) {
5222                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5223                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5224                        numProcs++;
5225                        try {
5226                            synchronized (observer) {
5227                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5228                                        + stats.pid);
5229                                final long stime = SystemClock.elapsedRealtime();
5230                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5231                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5232                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5233                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5234                            }
5235                        } catch (InterruptedException e) {
5236                            Slog.wtf(TAG, e);
5237                        }
5238                    } else if (DEBUG_ANR) {
5239                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5240                                + stats.pid);
5241                    }
5242                }
5243            }
5244        } finally {
5245            observer.stopWatching();
5246        }
5247    }
5248
5249    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5250        if (true || IS_USER_BUILD) {
5251            return;
5252        }
5253        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5254        if (tracesPath == null || tracesPath.length() == 0) {
5255            return;
5256        }
5257
5258        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5259        StrictMode.allowThreadDiskWrites();
5260        try {
5261            final File tracesFile = new File(tracesPath);
5262            final File tracesDir = tracesFile.getParentFile();
5263            final File tracesTmp = new File(tracesDir, "__tmp__");
5264            try {
5265                if (tracesFile.exists()) {
5266                    tracesTmp.delete();
5267                    tracesFile.renameTo(tracesTmp);
5268                }
5269                StringBuilder sb = new StringBuilder();
5270                Time tobj = new Time();
5271                tobj.set(System.currentTimeMillis());
5272                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5273                sb.append(": ");
5274                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5275                sb.append(" since ");
5276                sb.append(msg);
5277                FileOutputStream fos = new FileOutputStream(tracesFile);
5278                fos.write(sb.toString().getBytes());
5279                if (app == null) {
5280                    fos.write("\n*** No application process!".getBytes());
5281                }
5282                fos.close();
5283                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5284            } catch (IOException e) {
5285                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5286                return;
5287            }
5288
5289            if (app != null) {
5290                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5291                firstPids.add(app.pid);
5292                dumpStackTraces(tracesPath, firstPids, null, null, null);
5293            }
5294
5295            File lastTracesFile = null;
5296            File curTracesFile = null;
5297            for (int i=9; i>=0; i--) {
5298                String name = String.format(Locale.US, "slow%02d.txt", i);
5299                curTracesFile = new File(tracesDir, name);
5300                if (curTracesFile.exists()) {
5301                    if (lastTracesFile != null) {
5302                        curTracesFile.renameTo(lastTracesFile);
5303                    } else {
5304                        curTracesFile.delete();
5305                    }
5306                }
5307                lastTracesFile = curTracesFile;
5308            }
5309            tracesFile.renameTo(curTracesFile);
5310            if (tracesTmp.exists()) {
5311                tracesTmp.renameTo(tracesFile);
5312            }
5313        } finally {
5314            StrictMode.setThreadPolicy(oldPolicy);
5315        }
5316    }
5317
5318    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5319        if (!mLaunchWarningShown) {
5320            mLaunchWarningShown = true;
5321            mUiHandler.post(new Runnable() {
5322                @Override
5323                public void run() {
5324                    synchronized (ActivityManagerService.this) {
5325                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5326                        d.show();
5327                        mUiHandler.postDelayed(new Runnable() {
5328                            @Override
5329                            public void run() {
5330                                synchronized (ActivityManagerService.this) {
5331                                    d.dismiss();
5332                                    mLaunchWarningShown = false;
5333                                }
5334                            }
5335                        }, 4000);
5336                    }
5337                }
5338            });
5339        }
5340    }
5341
5342    @Override
5343    public boolean clearApplicationUserData(final String packageName,
5344            final IPackageDataObserver observer, int userId) {
5345        enforceNotIsolatedCaller("clearApplicationUserData");
5346        int uid = Binder.getCallingUid();
5347        int pid = Binder.getCallingPid();
5348        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5349                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5350
5351
5352        long callingId = Binder.clearCallingIdentity();
5353        try {
5354            IPackageManager pm = AppGlobals.getPackageManager();
5355            int pkgUid = -1;
5356            synchronized(this) {
5357                if (getPackageManagerInternalLocked().isPackageDataProtected(
5358                        userId, packageName)) {
5359                    throw new SecurityException(
5360                            "Cannot clear data for a protected package: " + packageName);
5361                }
5362
5363                try {
5364                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5365                } catch (RemoteException e) {
5366                }
5367                if (pkgUid == -1) {
5368                    Slog.w(TAG, "Invalid packageName: " + packageName);
5369                    if (observer != null) {
5370                        try {
5371                            observer.onRemoveCompleted(packageName, false);
5372                        } catch (RemoteException e) {
5373                            Slog.i(TAG, "Observer no longer exists.");
5374                        }
5375                    }
5376                    return false;
5377                }
5378                if (uid == pkgUid || checkComponentPermission(
5379                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5380                        pid, uid, -1, true)
5381                        == PackageManager.PERMISSION_GRANTED) {
5382                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5383                } else {
5384                    throw new SecurityException("PID " + pid + " does not have permission "
5385                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5386                                    + " of package " + packageName);
5387                }
5388
5389                // Remove all tasks match the cleared application package and user
5390                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5391                    final TaskRecord tr = mRecentTasks.get(i);
5392                    final String taskPackageName =
5393                            tr.getBaseIntent().getComponent().getPackageName();
5394                    if (tr.userId != userId) continue;
5395                    if (!taskPackageName.equals(packageName)) continue;
5396                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5397                }
5398            }
5399
5400            final int pkgUidF = pkgUid;
5401            final int userIdF = userId;
5402            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5403                @Override
5404                public void onRemoveCompleted(String packageName, boolean succeeded)
5405                        throws RemoteException {
5406                    synchronized (ActivityManagerService.this) {
5407                        finishForceStopPackageLocked(packageName, pkgUidF);
5408                    }
5409
5410                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5411                            Uri.fromParts("package", packageName, null));
5412                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5413                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5414                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5415                            null, null, 0, null, null, null, null, false, false, userIdF);
5416
5417                    if (observer != null) {
5418                        observer.onRemoveCompleted(packageName, succeeded);
5419                    }
5420                }
5421            };
5422
5423            try {
5424                // Clear application user data
5425                pm.clearApplicationUserData(packageName, localObserver, userId);
5426
5427                synchronized(this) {
5428                    // Remove all permissions granted from/to this package
5429                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5430                }
5431
5432                // Remove all zen rules created by this package; revoke it's zen access.
5433                INotificationManager inm = NotificationManager.getService();
5434                inm.removeAutomaticZenRules(packageName);
5435                inm.setNotificationPolicyAccessGranted(packageName, false);
5436
5437            } catch (RemoteException e) {
5438            }
5439        } finally {
5440            Binder.restoreCallingIdentity(callingId);
5441        }
5442        return true;
5443    }
5444
5445    @Override
5446    public void killBackgroundProcesses(final String packageName, int userId) {
5447        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5448                != PackageManager.PERMISSION_GRANTED &&
5449                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5450                        != PackageManager.PERMISSION_GRANTED) {
5451            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5452                    + Binder.getCallingPid()
5453                    + ", uid=" + Binder.getCallingUid()
5454                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5455            Slog.w(TAG, msg);
5456            throw new SecurityException(msg);
5457        }
5458
5459        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5460                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5461        long callingId = Binder.clearCallingIdentity();
5462        try {
5463            IPackageManager pm = AppGlobals.getPackageManager();
5464            synchronized(this) {
5465                int appId = -1;
5466                try {
5467                    appId = UserHandle.getAppId(
5468                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5469                } catch (RemoteException e) {
5470                }
5471                if (appId == -1) {
5472                    Slog.w(TAG, "Invalid packageName: " + packageName);
5473                    return;
5474                }
5475                killPackageProcessesLocked(packageName, appId, userId,
5476                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5477            }
5478        } finally {
5479            Binder.restoreCallingIdentity(callingId);
5480        }
5481    }
5482
5483    @Override
5484    public void killAllBackgroundProcesses() {
5485        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5486                != PackageManager.PERMISSION_GRANTED) {
5487            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5488                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5489                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5490            Slog.w(TAG, msg);
5491            throw new SecurityException(msg);
5492        }
5493
5494        final long callingId = Binder.clearCallingIdentity();
5495        try {
5496            synchronized (this) {
5497                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5498                final int NP = mProcessNames.getMap().size();
5499                for (int ip = 0; ip < NP; ip++) {
5500                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5501                    final int NA = apps.size();
5502                    for (int ia = 0; ia < NA; ia++) {
5503                        final ProcessRecord app = apps.valueAt(ia);
5504                        if (app.persistent) {
5505                            // We don't kill persistent processes.
5506                            continue;
5507                        }
5508                        if (app.removed) {
5509                            procs.add(app);
5510                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5511                            app.removed = true;
5512                            procs.add(app);
5513                        }
5514                    }
5515                }
5516
5517                final int N = procs.size();
5518                for (int i = 0; i < N; i++) {
5519                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5520                }
5521
5522                mAllowLowerMemLevel = true;
5523
5524                updateOomAdjLocked();
5525                doLowMemReportIfNeededLocked(null);
5526            }
5527        } finally {
5528            Binder.restoreCallingIdentity(callingId);
5529        }
5530    }
5531
5532    /**
5533     * Kills all background processes, except those matching any of the
5534     * specified properties.
5535     *
5536     * @param minTargetSdk the target SDK version at or above which to preserve
5537     *                     processes, or {@code -1} to ignore the target SDK
5538     * @param maxProcState the process state at or below which to preserve
5539     *                     processes, or {@code -1} to ignore the process state
5540     */
5541    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5542        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5543                != PackageManager.PERMISSION_GRANTED) {
5544            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5545                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5546                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5547            Slog.w(TAG, msg);
5548            throw new SecurityException(msg);
5549        }
5550
5551        final long callingId = Binder.clearCallingIdentity();
5552        try {
5553            synchronized (this) {
5554                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5555                final int NP = mProcessNames.getMap().size();
5556                for (int ip = 0; ip < NP; ip++) {
5557                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5558                    final int NA = apps.size();
5559                    for (int ia = 0; ia < NA; ia++) {
5560                        final ProcessRecord app = apps.valueAt(ia);
5561                        if (app.removed) {
5562                            procs.add(app);
5563                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5564                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5565                            app.removed = true;
5566                            procs.add(app);
5567                        }
5568                    }
5569                }
5570
5571                final int N = procs.size();
5572                for (int i = 0; i < N; i++) {
5573                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5574                }
5575            }
5576        } finally {
5577            Binder.restoreCallingIdentity(callingId);
5578        }
5579    }
5580
5581    @Override
5582    public void forceStopPackage(final String packageName, int userId) {
5583        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5584                != PackageManager.PERMISSION_GRANTED) {
5585            String msg = "Permission Denial: forceStopPackage() from pid="
5586                    + Binder.getCallingPid()
5587                    + ", uid=" + Binder.getCallingUid()
5588                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5589            Slog.w(TAG, msg);
5590            throw new SecurityException(msg);
5591        }
5592        final int callingPid = Binder.getCallingPid();
5593        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5594                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5595        long callingId = Binder.clearCallingIdentity();
5596        try {
5597            IPackageManager pm = AppGlobals.getPackageManager();
5598            synchronized(this) {
5599                int[] users = userId == UserHandle.USER_ALL
5600                        ? mUserController.getUsers() : new int[] { userId };
5601                for (int user : users) {
5602                    int pkgUid = -1;
5603                    try {
5604                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5605                                user);
5606                    } catch (RemoteException e) {
5607                    }
5608                    if (pkgUid == -1) {
5609                        Slog.w(TAG, "Invalid packageName: " + packageName);
5610                        continue;
5611                    }
5612                    try {
5613                        pm.setPackageStoppedState(packageName, true, user);
5614                    } catch (RemoteException e) {
5615                    } catch (IllegalArgumentException e) {
5616                        Slog.w(TAG, "Failed trying to unstop package "
5617                                + packageName + ": " + e);
5618                    }
5619                    if (mUserController.isUserRunningLocked(user, 0)) {
5620                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5621                        finishForceStopPackageLocked(packageName, pkgUid);
5622                    }
5623                }
5624            }
5625        } finally {
5626            Binder.restoreCallingIdentity(callingId);
5627        }
5628    }
5629
5630    @Override
5631    public void addPackageDependency(String packageName) {
5632        synchronized (this) {
5633            int callingPid = Binder.getCallingPid();
5634            if (callingPid == Process.myPid()) {
5635                //  Yeah, um, no.
5636                return;
5637            }
5638            ProcessRecord proc;
5639            synchronized (mPidsSelfLocked) {
5640                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5641            }
5642            if (proc != null) {
5643                if (proc.pkgDeps == null) {
5644                    proc.pkgDeps = new ArraySet<String>(1);
5645                }
5646                proc.pkgDeps.add(packageName);
5647            }
5648        }
5649    }
5650
5651    /*
5652     * The pkg name and app id have to be specified.
5653     */
5654    @Override
5655    public void killApplication(String pkg, int appId, int userId, String reason) {
5656        if (pkg == null) {
5657            return;
5658        }
5659        // Make sure the uid is valid.
5660        if (appId < 0) {
5661            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5662            return;
5663        }
5664        int callerUid = Binder.getCallingUid();
5665        // Only the system server can kill an application
5666        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5667            // Post an aysnc message to kill the application
5668            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5669            msg.arg1 = appId;
5670            msg.arg2 = userId;
5671            Bundle bundle = new Bundle();
5672            bundle.putString("pkg", pkg);
5673            bundle.putString("reason", reason);
5674            msg.obj = bundle;
5675            mHandler.sendMessage(msg);
5676        } else {
5677            throw new SecurityException(callerUid + " cannot kill pkg: " +
5678                    pkg);
5679        }
5680    }
5681
5682    @Override
5683    public void closeSystemDialogs(String reason) {
5684        enforceNotIsolatedCaller("closeSystemDialogs");
5685
5686        final int pid = Binder.getCallingPid();
5687        final int uid = Binder.getCallingUid();
5688        final long origId = Binder.clearCallingIdentity();
5689        try {
5690            synchronized (this) {
5691                // Only allow this from foreground processes, so that background
5692                // applications can't abuse it to prevent system UI from being shown.
5693                if (uid >= Process.FIRST_APPLICATION_UID) {
5694                    ProcessRecord proc;
5695                    synchronized (mPidsSelfLocked) {
5696                        proc = mPidsSelfLocked.get(pid);
5697                    }
5698                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5699                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5700                                + " from background process " + proc);
5701                        return;
5702                    }
5703                }
5704                closeSystemDialogsLocked(reason);
5705            }
5706        } finally {
5707            Binder.restoreCallingIdentity(origId);
5708        }
5709    }
5710
5711    void closeSystemDialogsLocked(String reason) {
5712        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5713        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5714                | Intent.FLAG_RECEIVER_FOREGROUND);
5715        if (reason != null) {
5716            intent.putExtra("reason", reason);
5717        }
5718        mWindowManager.closeSystemDialogs(reason);
5719
5720        mStackSupervisor.closeSystemDialogsLocked();
5721
5722        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5723                AppOpsManager.OP_NONE, null, false, false,
5724                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5725    }
5726
5727    @Override
5728    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5729        enforceNotIsolatedCaller("getProcessMemoryInfo");
5730        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5731        for (int i=pids.length-1; i>=0; i--) {
5732            ProcessRecord proc;
5733            int oomAdj;
5734            synchronized (this) {
5735                synchronized (mPidsSelfLocked) {
5736                    proc = mPidsSelfLocked.get(pids[i]);
5737                    oomAdj = proc != null ? proc.setAdj : 0;
5738                }
5739            }
5740            infos[i] = new Debug.MemoryInfo();
5741            Debug.getMemoryInfo(pids[i], infos[i]);
5742            if (proc != null) {
5743                synchronized (this) {
5744                    if (proc.thread != null && proc.setAdj == oomAdj) {
5745                        // Record this for posterity if the process has been stable.
5746                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5747                                infos[i].getTotalUss(), false, proc.pkgList);
5748                    }
5749                }
5750            }
5751        }
5752        return infos;
5753    }
5754
5755    @Override
5756    public long[] getProcessPss(int[] pids) {
5757        enforceNotIsolatedCaller("getProcessPss");
5758        long[] pss = new long[pids.length];
5759        for (int i=pids.length-1; i>=0; i--) {
5760            ProcessRecord proc;
5761            int oomAdj;
5762            synchronized (this) {
5763                synchronized (mPidsSelfLocked) {
5764                    proc = mPidsSelfLocked.get(pids[i]);
5765                    oomAdj = proc != null ? proc.setAdj : 0;
5766                }
5767            }
5768            long[] tmpUss = new long[1];
5769            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5770            if (proc != null) {
5771                synchronized (this) {
5772                    if (proc.thread != null && proc.setAdj == oomAdj) {
5773                        // Record this for posterity if the process has been stable.
5774                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5775                    }
5776                }
5777            }
5778        }
5779        return pss;
5780    }
5781
5782    @Override
5783    public void killApplicationProcess(String processName, int uid) {
5784        if (processName == null) {
5785            return;
5786        }
5787
5788        int callerUid = Binder.getCallingUid();
5789        // Only the system server can kill an application
5790        if (callerUid == Process.SYSTEM_UID) {
5791            synchronized (this) {
5792                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5793                if (app != null && app.thread != null) {
5794                    try {
5795                        app.thread.scheduleSuicide();
5796                    } catch (RemoteException e) {
5797                        // If the other end already died, then our work here is done.
5798                    }
5799                } else {
5800                    Slog.w(TAG, "Process/uid not found attempting kill of "
5801                            + processName + " / " + uid);
5802                }
5803            }
5804        } else {
5805            throw new SecurityException(callerUid + " cannot kill app process: " +
5806                    processName);
5807        }
5808    }
5809
5810    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5811        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5812                false, true, false, false, UserHandle.getUserId(uid), reason);
5813    }
5814
5815    private void finishForceStopPackageLocked(final String packageName, int uid) {
5816        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5817                Uri.fromParts("package", packageName, null));
5818        if (!mProcessesReady) {
5819            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5820                    | Intent.FLAG_RECEIVER_FOREGROUND);
5821        }
5822        intent.putExtra(Intent.EXTRA_UID, uid);
5823        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5824        broadcastIntentLocked(null, null, intent,
5825                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5826                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5827    }
5828
5829
5830    private final boolean killPackageProcessesLocked(String packageName, int appId,
5831            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5832            boolean doit, boolean evenPersistent, String reason) {
5833        ArrayList<ProcessRecord> procs = new ArrayList<>();
5834
5835        // Remove all processes this package may have touched: all with the
5836        // same UID (except for the system or root user), and all whose name
5837        // matches the package name.
5838        final int NP = mProcessNames.getMap().size();
5839        for (int ip=0; ip<NP; ip++) {
5840            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5841            final int NA = apps.size();
5842            for (int ia=0; ia<NA; ia++) {
5843                ProcessRecord app = apps.valueAt(ia);
5844                if (app.persistent && !evenPersistent) {
5845                    // we don't kill persistent processes
5846                    continue;
5847                }
5848                if (app.removed) {
5849                    if (doit) {
5850                        procs.add(app);
5851                    }
5852                    continue;
5853                }
5854
5855                // Skip process if it doesn't meet our oom adj requirement.
5856                if (app.setAdj < minOomAdj) {
5857                    continue;
5858                }
5859
5860                // If no package is specified, we call all processes under the
5861                // give user id.
5862                if (packageName == null) {
5863                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5864                        continue;
5865                    }
5866                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5867                        continue;
5868                    }
5869                // Package has been specified, we want to hit all processes
5870                // that match it.  We need to qualify this by the processes
5871                // that are running under the specified app and user ID.
5872                } else {
5873                    final boolean isDep = app.pkgDeps != null
5874                            && app.pkgDeps.contains(packageName);
5875                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5876                        continue;
5877                    }
5878                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5879                        continue;
5880                    }
5881                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5882                        continue;
5883                    }
5884                }
5885
5886                // Process has passed all conditions, kill it!
5887                if (!doit) {
5888                    return true;
5889                }
5890                app.removed = true;
5891                procs.add(app);
5892            }
5893        }
5894
5895        int N = procs.size();
5896        for (int i=0; i<N; i++) {
5897            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5898        }
5899        updateOomAdjLocked();
5900        return N > 0;
5901    }
5902
5903    private void cleanupDisabledPackageComponentsLocked(
5904            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5905
5906        Set<String> disabledClasses = null;
5907        boolean packageDisabled = false;
5908        IPackageManager pm = AppGlobals.getPackageManager();
5909
5910        if (changedClasses == null) {
5911            // Nothing changed...
5912            return;
5913        }
5914
5915        // Determine enable/disable state of the package and its components.
5916        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5917        for (int i = changedClasses.length - 1; i >= 0; i--) {
5918            final String changedClass = changedClasses[i];
5919
5920            if (changedClass.equals(packageName)) {
5921                try {
5922                    // Entire package setting changed
5923                    enabled = pm.getApplicationEnabledSetting(packageName,
5924                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5925                } catch (Exception e) {
5926                    // No such package/component; probably racing with uninstall.  In any
5927                    // event it means we have nothing further to do here.
5928                    return;
5929                }
5930                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5931                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5932                if (packageDisabled) {
5933                    // Entire package is disabled.
5934                    // No need to continue to check component states.
5935                    disabledClasses = null;
5936                    break;
5937                }
5938            } else {
5939                try {
5940                    enabled = pm.getComponentEnabledSetting(
5941                            new ComponentName(packageName, changedClass),
5942                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5943                } catch (Exception e) {
5944                    // As above, probably racing with uninstall.
5945                    return;
5946                }
5947                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5948                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5949                    if (disabledClasses == null) {
5950                        disabledClasses = new ArraySet<>(changedClasses.length);
5951                    }
5952                    disabledClasses.add(changedClass);
5953                }
5954            }
5955        }
5956
5957        if (!packageDisabled && disabledClasses == null) {
5958            // Nothing to do here...
5959            return;
5960        }
5961
5962        // Clean-up disabled activities.
5963        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5964                packageName, disabledClasses, true, false, userId) && mBooted) {
5965            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5966            mStackSupervisor.scheduleIdleLocked();
5967        }
5968
5969        // Clean-up disabled tasks
5970        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5971
5972        // Clean-up disabled services.
5973        mServices.bringDownDisabledPackageServicesLocked(
5974                packageName, disabledClasses, userId, false, killProcess, true);
5975
5976        // Clean-up disabled providers.
5977        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5978        mProviderMap.collectPackageProvidersLocked(
5979                packageName, disabledClasses, true, false, userId, providers);
5980        for (int i = providers.size() - 1; i >= 0; i--) {
5981            removeDyingProviderLocked(null, providers.get(i), true);
5982        }
5983
5984        // Clean-up disabled broadcast receivers.
5985        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5986            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5987                    packageName, disabledClasses, userId, true);
5988        }
5989
5990    }
5991
5992    final boolean clearBroadcastQueueForUserLocked(int userId) {
5993        boolean didSomething = false;
5994        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5995            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5996                    null, null, userId, true);
5997        }
5998        return didSomething;
5999    }
6000
6001    final boolean forceStopPackageLocked(String packageName, int appId,
6002            boolean callerWillRestart, boolean purgeCache, boolean doit,
6003            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6004        int i;
6005
6006        if (userId == UserHandle.USER_ALL && packageName == null) {
6007            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6008        }
6009
6010        if (appId < 0 && packageName != null) {
6011            try {
6012                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6013                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6014            } catch (RemoteException e) {
6015            }
6016        }
6017
6018        if (doit) {
6019            if (packageName != null) {
6020                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6021                        + " user=" + userId + ": " + reason);
6022            } else {
6023                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6024            }
6025
6026            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6027        }
6028
6029        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6030                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6031                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6032
6033        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6034
6035        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6036                packageName, null, doit, evenPersistent, userId)) {
6037            if (!doit) {
6038                return true;
6039            }
6040            didSomething = true;
6041        }
6042
6043        if (mServices.bringDownDisabledPackageServicesLocked(
6044                packageName, null, userId, evenPersistent, true, doit)) {
6045            if (!doit) {
6046                return true;
6047            }
6048            didSomething = true;
6049        }
6050
6051        if (packageName == null) {
6052            // Remove all sticky broadcasts from this user.
6053            mStickyBroadcasts.remove(userId);
6054        }
6055
6056        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6057        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6058                userId, providers)) {
6059            if (!doit) {
6060                return true;
6061            }
6062            didSomething = true;
6063        }
6064        for (i = providers.size() - 1; i >= 0; i--) {
6065            removeDyingProviderLocked(null, providers.get(i), true);
6066        }
6067
6068        // Remove transient permissions granted from/to this package/user
6069        removeUriPermissionsForPackageLocked(packageName, userId, false);
6070
6071        if (doit) {
6072            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6073                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6074                        packageName, null, userId, doit);
6075            }
6076        }
6077
6078        if (packageName == null || uninstalling) {
6079            // Remove pending intents.  For now we only do this when force
6080            // stopping users, because we have some problems when doing this
6081            // for packages -- app widgets are not currently cleaned up for
6082            // such packages, so they can be left with bad pending intents.
6083            if (mIntentSenderRecords.size() > 0) {
6084                Iterator<WeakReference<PendingIntentRecord>> it
6085                        = mIntentSenderRecords.values().iterator();
6086                while (it.hasNext()) {
6087                    WeakReference<PendingIntentRecord> wpir = it.next();
6088                    if (wpir == null) {
6089                        it.remove();
6090                        continue;
6091                    }
6092                    PendingIntentRecord pir = wpir.get();
6093                    if (pir == null) {
6094                        it.remove();
6095                        continue;
6096                    }
6097                    if (packageName == null) {
6098                        // Stopping user, remove all objects for the user.
6099                        if (pir.key.userId != userId) {
6100                            // Not the same user, skip it.
6101                            continue;
6102                        }
6103                    } else {
6104                        if (UserHandle.getAppId(pir.uid) != appId) {
6105                            // Different app id, skip it.
6106                            continue;
6107                        }
6108                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6109                            // Different user, skip it.
6110                            continue;
6111                        }
6112                        if (!pir.key.packageName.equals(packageName)) {
6113                            // Different package, skip it.
6114                            continue;
6115                        }
6116                    }
6117                    if (!doit) {
6118                        return true;
6119                    }
6120                    didSomething = true;
6121                    it.remove();
6122                    pir.canceled = true;
6123                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6124                        pir.key.activity.pendingResults.remove(pir.ref);
6125                    }
6126                }
6127            }
6128        }
6129
6130        if (doit) {
6131            if (purgeCache && packageName != null) {
6132                AttributeCache ac = AttributeCache.instance();
6133                if (ac != null) {
6134                    ac.removePackage(packageName);
6135                }
6136            }
6137            if (mBooted) {
6138                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6139                mStackSupervisor.scheduleIdleLocked();
6140            }
6141        }
6142
6143        return didSomething;
6144    }
6145
6146    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6147        ProcessRecord old = mProcessNames.remove(name, uid);
6148        if (old != null) {
6149            old.uidRecord.numProcs--;
6150            if (old.uidRecord.numProcs == 0) {
6151                // No more processes using this uid, tell clients it is gone.
6152                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6153                        "No more processes in " + old.uidRecord);
6154                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6155                mActiveUids.remove(uid);
6156                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6157            }
6158            old.uidRecord = null;
6159        }
6160        mIsolatedProcesses.remove(uid);
6161        return old;
6162    }
6163
6164    private final void addProcessNameLocked(ProcessRecord proc) {
6165        // We shouldn't already have a process under this name, but just in case we
6166        // need to clean up whatever may be there now.
6167        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6168        if (old == proc && proc.persistent) {
6169            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6170            Slog.w(TAG, "Re-adding persistent process " + proc);
6171        } else if (old != null) {
6172            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6173        }
6174        UidRecord uidRec = mActiveUids.get(proc.uid);
6175        if (uidRec == null) {
6176            uidRec = new UidRecord(proc.uid);
6177            // This is the first appearance of the uid, report it now!
6178            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6179                    "Creating new process uid: " + uidRec);
6180            mActiveUids.put(proc.uid, uidRec);
6181            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6182            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6183        }
6184        proc.uidRecord = uidRec;
6185
6186        // Reset render thread tid if it was already set, so new process can set it again.
6187        proc.renderThreadTid = 0;
6188        uidRec.numProcs++;
6189        mProcessNames.put(proc.processName, proc.uid, proc);
6190        if (proc.isolated) {
6191            mIsolatedProcesses.put(proc.uid, proc);
6192        }
6193    }
6194
6195    boolean removeProcessLocked(ProcessRecord app,
6196            boolean callerWillRestart, boolean allowRestart, String reason) {
6197        final String name = app.processName;
6198        final int uid = app.uid;
6199        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6200            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6201
6202        ProcessRecord old = mProcessNames.get(name, uid);
6203        if (old != app) {
6204            // This process is no longer active, so nothing to do.
6205            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6206            return false;
6207        }
6208        removeProcessNameLocked(name, uid);
6209        if (mHeavyWeightProcess == app) {
6210            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6211                    mHeavyWeightProcess.userId, 0));
6212            mHeavyWeightProcess = null;
6213        }
6214        boolean needRestart = false;
6215        if (app.pid > 0 && app.pid != MY_PID) {
6216            int pid = app.pid;
6217            synchronized (mPidsSelfLocked) {
6218                mPidsSelfLocked.remove(pid);
6219                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6220            }
6221            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6222            if (app.isolated) {
6223                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6224            }
6225            boolean willRestart = false;
6226            if (app.persistent && !app.isolated) {
6227                if (!callerWillRestart) {
6228                    willRestart = true;
6229                } else {
6230                    needRestart = true;
6231                }
6232            }
6233            app.kill(reason, true);
6234            handleAppDiedLocked(app, willRestart, allowRestart);
6235            if (willRestart) {
6236                removeLruProcessLocked(app);
6237                addAppLocked(app.info, false, null /* ABI override */);
6238            }
6239        } else {
6240            mRemovedProcesses.add(app);
6241        }
6242
6243        return needRestart;
6244    }
6245
6246    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6247        cleanupAppInLaunchingProvidersLocked(app, true);
6248        removeProcessLocked(app, false, true, "timeout publishing content providers");
6249    }
6250
6251    private final void processStartTimedOutLocked(ProcessRecord app) {
6252        final int pid = app.pid;
6253        boolean gone = false;
6254        synchronized (mPidsSelfLocked) {
6255            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6256            if (knownApp != null && knownApp.thread == null) {
6257                mPidsSelfLocked.remove(pid);
6258                gone = true;
6259            }
6260        }
6261
6262        if (gone) {
6263            Slog.w(TAG, "Process " + app + " failed to attach");
6264            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6265                    pid, app.uid, app.processName);
6266            removeProcessNameLocked(app.processName, app.uid);
6267            if (mHeavyWeightProcess == app) {
6268                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6269                        mHeavyWeightProcess.userId, 0));
6270                mHeavyWeightProcess = null;
6271            }
6272            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6273            if (app.isolated) {
6274                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6275            }
6276            // Take care of any launching providers waiting for this process.
6277            cleanupAppInLaunchingProvidersLocked(app, true);
6278            // Take care of any services that are waiting for the process.
6279            mServices.processStartTimedOutLocked(app);
6280            app.kill("start timeout", true);
6281            removeLruProcessLocked(app);
6282            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6283                Slog.w(TAG, "Unattached app died before backup, skipping");
6284                try {
6285                    IBackupManager bm = IBackupManager.Stub.asInterface(
6286                            ServiceManager.getService(Context.BACKUP_SERVICE));
6287                    bm.agentDisconnected(app.info.packageName);
6288                } catch (RemoteException e) {
6289                    // Can't happen; the backup manager is local
6290                }
6291            }
6292            if (isPendingBroadcastProcessLocked(pid)) {
6293                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6294                skipPendingBroadcastLocked(pid);
6295            }
6296        } else {
6297            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6298        }
6299    }
6300
6301    private final boolean attachApplicationLocked(IApplicationThread thread,
6302            int pid) {
6303
6304        // Find the application record that is being attached...  either via
6305        // the pid if we are running in multiple processes, or just pull the
6306        // next app record if we are emulating process with anonymous threads.
6307        ProcessRecord app;
6308        if (pid != MY_PID && pid >= 0) {
6309            synchronized (mPidsSelfLocked) {
6310                app = mPidsSelfLocked.get(pid);
6311            }
6312        } else {
6313            app = null;
6314        }
6315
6316        if (app == null) {
6317            Slog.w(TAG, "No pending application record for pid " + pid
6318                    + " (IApplicationThread " + thread + "); dropping process");
6319            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6320            if (pid > 0 && pid != MY_PID) {
6321                Process.killProcessQuiet(pid);
6322                //TODO: killProcessGroup(app.info.uid, pid);
6323            } else {
6324                try {
6325                    thread.scheduleExit();
6326                } catch (Exception e) {
6327                    // Ignore exceptions.
6328                }
6329            }
6330            return false;
6331        }
6332
6333        // If this application record is still attached to a previous
6334        // process, clean it up now.
6335        if (app.thread != null) {
6336            handleAppDiedLocked(app, true, true);
6337        }
6338
6339        // Tell the process all about itself.
6340
6341        if (DEBUG_ALL) Slog.v(
6342                TAG, "Binding process pid " + pid + " to record " + app);
6343
6344        final String processName = app.processName;
6345        try {
6346            AppDeathRecipient adr = new AppDeathRecipient(
6347                    app, pid, thread);
6348            thread.asBinder().linkToDeath(adr, 0);
6349            app.deathRecipient = adr;
6350        } catch (RemoteException e) {
6351            app.resetPackageList(mProcessStats);
6352            startProcessLocked(app, "link fail", processName);
6353            return false;
6354        }
6355
6356        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6357
6358        app.makeActive(thread, mProcessStats);
6359        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6360        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6361        app.forcingToForeground = null;
6362        updateProcessForegroundLocked(app, false, false);
6363        app.hasShownUi = false;
6364        app.debugging = false;
6365        app.cached = false;
6366        app.killedByAm = false;
6367        app.killed = false;
6368
6369
6370        // We carefully use the same state that PackageManager uses for
6371        // filtering, since we use this flag to decide if we need to install
6372        // providers when user is unlocked later
6373        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6374
6375        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6376
6377        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6378        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6379
6380        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6381            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6382            msg.obj = app;
6383            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6384        }
6385
6386        if (!normalMode) {
6387            Slog.i(TAG, "Launching preboot mode app: " + app);
6388        }
6389
6390        if (DEBUG_ALL) Slog.v(
6391            TAG, "New app record " + app
6392            + " thread=" + thread.asBinder() + " pid=" + pid);
6393        try {
6394            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6395            if (mDebugApp != null && mDebugApp.equals(processName)) {
6396                testMode = mWaitForDebugger
6397                    ? ApplicationThreadConstants.DEBUG_WAIT
6398                    : ApplicationThreadConstants.DEBUG_ON;
6399                app.debugging = true;
6400                if (mDebugTransient) {
6401                    mDebugApp = mOrigDebugApp;
6402                    mWaitForDebugger = mOrigWaitForDebugger;
6403                }
6404            }
6405            String profileFile = app.instrumentationProfileFile;
6406            ParcelFileDescriptor profileFd = null;
6407            int samplingInterval = 0;
6408            boolean profileAutoStop = false;
6409            if (mProfileApp != null && mProfileApp.equals(processName)) {
6410                mProfileProc = app;
6411                profileFile = mProfileFile;
6412                profileFd = mProfileFd;
6413                samplingInterval = mSamplingInterval;
6414                profileAutoStop = mAutoStopProfiler;
6415            }
6416            boolean enableTrackAllocation = false;
6417            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6418                enableTrackAllocation = true;
6419                mTrackAllocationApp = null;
6420            }
6421
6422            // If the app is being launched for restore or full backup, set it up specially
6423            boolean isRestrictedBackupMode = false;
6424            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6425                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6426                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6427                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6428                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6429            }
6430
6431            if (app.instrumentationClass != null) {
6432                notifyPackageUse(app.instrumentationClass.getPackageName(),
6433                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6434            }
6435            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6436                    + processName + " with config " + getGlobalConfiguration());
6437            ApplicationInfo appInfo = app.instrumentationInfo != null
6438                    ? app.instrumentationInfo : app.info;
6439            app.compat = compatibilityInfoForPackageLocked(appInfo);
6440            if (profileFd != null) {
6441                profileFd = profileFd.dup();
6442            }
6443            ProfilerInfo profilerInfo = profileFile == null ? null
6444                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6445
6446            // We deprecated Build.SERIAL and only apps that target pre NMR1
6447            // SDK can see it. Since access to the serial is now behind a
6448            // permission we push down the value.
6449            String buildSerial = Build.UNKNOWN;
6450            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6451                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6452                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6453                        .getSerial();
6454            }
6455
6456            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6457                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6458                    app.instrumentationUiAutomationConnection, testMode,
6459                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6460                    isRestrictedBackupMode || !normalMode, app.persistent,
6461                    new Configuration(getGlobalConfiguration()), app.compat,
6462                    getCommonServicesLocked(app.isolated),
6463                    mCoreSettingsObserver.getCoreSettingsLocked(),
6464                    buildSerial);
6465
6466            updateLruProcessLocked(app, false, null);
6467            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6468        } catch (Exception e) {
6469            // todo: Yikes!  What should we do?  For now we will try to
6470            // start another process, but that could easily get us in
6471            // an infinite loop of restarting processes...
6472            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6473
6474            app.resetPackageList(mProcessStats);
6475            app.unlinkDeathRecipient();
6476            startProcessLocked(app, "bind fail", processName);
6477            return false;
6478        }
6479
6480        // Remove this record from the list of starting applications.
6481        mPersistentStartingProcesses.remove(app);
6482        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6483                "Attach application locked removing on hold: " + app);
6484        mProcessesOnHold.remove(app);
6485
6486        boolean badApp = false;
6487        boolean didSomething = false;
6488
6489        // See if the top visible activity is waiting to run in this process...
6490        if (normalMode) {
6491            try {
6492                if (mStackSupervisor.attachApplicationLocked(app)) {
6493                    didSomething = true;
6494                }
6495            } catch (Exception e) {
6496                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6497                badApp = true;
6498            }
6499        }
6500
6501        // Find any services that should be running in this process...
6502        if (!badApp) {
6503            try {
6504                didSomething |= mServices.attachApplicationLocked(app, processName);
6505            } catch (Exception e) {
6506                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6507                badApp = true;
6508            }
6509        }
6510
6511        // Check if a next-broadcast receiver is in this process...
6512        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6513            try {
6514                didSomething |= sendPendingBroadcastsLocked(app);
6515            } catch (Exception e) {
6516                // If the app died trying to launch the receiver we declare it 'bad'
6517                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6518                badApp = true;
6519            }
6520        }
6521
6522        // Check whether the next backup agent is in this process...
6523        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6524            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6525                    "New app is backup target, launching agent for " + app);
6526            notifyPackageUse(mBackupTarget.appInfo.packageName,
6527                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6528            try {
6529                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6530                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6531                        mBackupTarget.backupMode);
6532            } catch (Exception e) {
6533                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6534                badApp = true;
6535            }
6536        }
6537
6538        if (badApp) {
6539            app.kill("error during init", true);
6540            handleAppDiedLocked(app, false, true);
6541            return false;
6542        }
6543
6544        if (!didSomething) {
6545            updateOomAdjLocked();
6546        }
6547
6548        return true;
6549    }
6550
6551    @Override
6552    public final void attachApplication(IApplicationThread thread) {
6553        synchronized (this) {
6554            int callingPid = Binder.getCallingPid();
6555            final long origId = Binder.clearCallingIdentity();
6556            attachApplicationLocked(thread, callingPid);
6557            Binder.restoreCallingIdentity(origId);
6558        }
6559    }
6560
6561    @Override
6562    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6563        final long origId = Binder.clearCallingIdentity();
6564        synchronized (this) {
6565            ActivityStack stack = ActivityRecord.getStackLocked(token);
6566            if (stack != null) {
6567                ActivityRecord r =
6568                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6569                if (stopProfiling) {
6570                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6571                        try {
6572                            mProfileFd.close();
6573                        } catch (IOException e) {
6574                        }
6575                        clearProfilerLocked();
6576                    }
6577                }
6578            }
6579        }
6580        Binder.restoreCallingIdentity(origId);
6581    }
6582
6583    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6584        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6585                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6586    }
6587
6588    void enableScreenAfterBoot() {
6589        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6590                SystemClock.uptimeMillis());
6591        mWindowManager.enableScreenAfterBoot();
6592
6593        synchronized (this) {
6594            updateEventDispatchingLocked();
6595        }
6596    }
6597
6598    @Override
6599    public void showBootMessage(final CharSequence msg, final boolean always) {
6600        if (Binder.getCallingUid() != Process.myUid()) {
6601            throw new SecurityException();
6602        }
6603        mWindowManager.showBootMessage(msg, always);
6604    }
6605
6606    @Override
6607    public void keyguardGoingAway(int flags) {
6608        enforceNotIsolatedCaller("keyguardGoingAway");
6609        final long token = Binder.clearCallingIdentity();
6610        try {
6611            synchronized (this) {
6612                mKeyguardController.keyguardGoingAway(flags);
6613            }
6614        } finally {
6615            Binder.restoreCallingIdentity(token);
6616        }
6617    }
6618
6619    final void finishBooting() {
6620        synchronized (this) {
6621            if (!mBootAnimationComplete) {
6622                mCallFinishBooting = true;
6623                return;
6624            }
6625            mCallFinishBooting = false;
6626        }
6627
6628        ArraySet<String> completedIsas = new ArraySet<String>();
6629        for (String abi : Build.SUPPORTED_ABIS) {
6630            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6631            final String instructionSet = VMRuntime.getInstructionSet(abi);
6632            if (!completedIsas.contains(instructionSet)) {
6633                try {
6634                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6635                } catch (InstallerException e) {
6636                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6637                            e.getMessage() +")");
6638                }
6639                completedIsas.add(instructionSet);
6640            }
6641        }
6642
6643        IntentFilter pkgFilter = new IntentFilter();
6644        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6645        pkgFilter.addDataScheme("package");
6646        mContext.registerReceiver(new BroadcastReceiver() {
6647            @Override
6648            public void onReceive(Context context, Intent intent) {
6649                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6650                if (pkgs != null) {
6651                    for (String pkg : pkgs) {
6652                        synchronized (ActivityManagerService.this) {
6653                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6654                                    0, "query restart")) {
6655                                setResultCode(Activity.RESULT_OK);
6656                                return;
6657                            }
6658                        }
6659                    }
6660                }
6661            }
6662        }, pkgFilter);
6663
6664        IntentFilter dumpheapFilter = new IntentFilter();
6665        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6666        mContext.registerReceiver(new BroadcastReceiver() {
6667            @Override
6668            public void onReceive(Context context, Intent intent) {
6669                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6670                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6671                } else {
6672                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6673                }
6674            }
6675        }, dumpheapFilter);
6676
6677        // Let system services know.
6678        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6679
6680        synchronized (this) {
6681            // Ensure that any processes we had put on hold are now started
6682            // up.
6683            final int NP = mProcessesOnHold.size();
6684            if (NP > 0) {
6685                ArrayList<ProcessRecord> procs =
6686                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6687                for (int ip=0; ip<NP; ip++) {
6688                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6689                            + procs.get(ip));
6690                    startProcessLocked(procs.get(ip), "on-hold", null);
6691                }
6692            }
6693
6694            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6695                // Start looking for apps that are abusing wake locks.
6696                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6697                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6698                // Tell anyone interested that we are done booting!
6699                SystemProperties.set("sys.boot_completed", "1");
6700
6701                // And trigger dev.bootcomplete if we are not showing encryption progress
6702                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6703                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6704                    SystemProperties.set("dev.bootcomplete", "1");
6705                }
6706                mUserController.sendBootCompletedLocked(
6707                        new IIntentReceiver.Stub() {
6708                            @Override
6709                            public void performReceive(Intent intent, int resultCode,
6710                                    String data, Bundle extras, boolean ordered,
6711                                    boolean sticky, int sendingUser) {
6712                                synchronized (ActivityManagerService.this) {
6713                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6714                                            true, false);
6715                                }
6716                            }
6717                        });
6718                scheduleStartProfilesLocked();
6719            }
6720        }
6721    }
6722
6723    @Override
6724    public void bootAnimationComplete() {
6725        final boolean callFinishBooting;
6726        synchronized (this) {
6727            callFinishBooting = mCallFinishBooting;
6728            mBootAnimationComplete = true;
6729        }
6730        if (callFinishBooting) {
6731            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6732            finishBooting();
6733            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6734        }
6735    }
6736
6737    final void ensureBootCompleted() {
6738        boolean booting;
6739        boolean enableScreen;
6740        synchronized (this) {
6741            booting = mBooting;
6742            mBooting = false;
6743            enableScreen = !mBooted;
6744            mBooted = true;
6745        }
6746
6747        if (booting) {
6748            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6749            finishBooting();
6750            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6751        }
6752
6753        if (enableScreen) {
6754            enableScreenAfterBoot();
6755        }
6756    }
6757
6758    @Override
6759    public final void activityResumed(IBinder token) {
6760        final long origId = Binder.clearCallingIdentity();
6761        synchronized(this) {
6762            ActivityRecord.activityResumedLocked(token);
6763            mWindowManager.notifyAppResumedFinished(token);
6764        }
6765        Binder.restoreCallingIdentity(origId);
6766    }
6767
6768    @Override
6769    public final void activityPaused(IBinder token) {
6770        final long origId = Binder.clearCallingIdentity();
6771        synchronized(this) {
6772            ActivityStack stack = ActivityRecord.getStackLocked(token);
6773            if (stack != null) {
6774                stack.activityPausedLocked(token, false);
6775            }
6776        }
6777        Binder.restoreCallingIdentity(origId);
6778    }
6779
6780    @Override
6781    public final void activityStopped(IBinder token, Bundle icicle,
6782            PersistableBundle persistentState, CharSequence description) {
6783        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6784
6785        // Refuse possible leaked file descriptors
6786        if (icicle != null && icicle.hasFileDescriptors()) {
6787            throw new IllegalArgumentException("File descriptors passed in Bundle");
6788        }
6789
6790        final long origId = Binder.clearCallingIdentity();
6791
6792        synchronized (this) {
6793            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6794            if (r != null) {
6795                r.activityStoppedLocked(icicle, persistentState, description);
6796            }
6797        }
6798
6799        trimApplications();
6800
6801        Binder.restoreCallingIdentity(origId);
6802    }
6803
6804    @Override
6805    public final void activityDestroyed(IBinder token) {
6806        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6807        synchronized (this) {
6808            ActivityStack stack = ActivityRecord.getStackLocked(token);
6809            if (stack != null) {
6810                stack.activityDestroyedLocked(token, "activityDestroyed");
6811            }
6812        }
6813    }
6814
6815    @Override
6816    public final void activityRelaunched(IBinder token) {
6817        final long origId = Binder.clearCallingIdentity();
6818        synchronized (this) {
6819            mStackSupervisor.activityRelaunchedLocked(token);
6820        }
6821        Binder.restoreCallingIdentity(origId);
6822    }
6823
6824    @Override
6825    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6826            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6827        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6828                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6829        synchronized (this) {
6830            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6831            if (record == null) {
6832                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6833                        + "found for: " + token);
6834            }
6835            record.setSizeConfigurations(horizontalSizeConfiguration,
6836                    verticalSizeConfigurations, smallestSizeConfigurations);
6837        }
6838    }
6839
6840    @Override
6841    public final void backgroundResourcesReleased(IBinder token) {
6842        final long origId = Binder.clearCallingIdentity();
6843        try {
6844            synchronized (this) {
6845                ActivityStack stack = ActivityRecord.getStackLocked(token);
6846                if (stack != null) {
6847                    stack.backgroundResourcesReleased();
6848                }
6849            }
6850        } finally {
6851            Binder.restoreCallingIdentity(origId);
6852        }
6853    }
6854
6855    @Override
6856    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6857        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6858    }
6859
6860    @Override
6861    public final void notifyEnterAnimationComplete(IBinder token) {
6862        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6863    }
6864
6865    @Override
6866    public String getCallingPackage(IBinder token) {
6867        synchronized (this) {
6868            ActivityRecord r = getCallingRecordLocked(token);
6869            return r != null ? r.info.packageName : null;
6870        }
6871    }
6872
6873    @Override
6874    public ComponentName getCallingActivity(IBinder token) {
6875        synchronized (this) {
6876            ActivityRecord r = getCallingRecordLocked(token);
6877            return r != null ? r.intent.getComponent() : null;
6878        }
6879    }
6880
6881    private ActivityRecord getCallingRecordLocked(IBinder token) {
6882        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6883        if (r == null) {
6884            return null;
6885        }
6886        return r.resultTo;
6887    }
6888
6889    @Override
6890    public ComponentName getActivityClassForToken(IBinder token) {
6891        synchronized(this) {
6892            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6893            if (r == null) {
6894                return null;
6895            }
6896            return r.intent.getComponent();
6897        }
6898    }
6899
6900    @Override
6901    public String getPackageForToken(IBinder token) {
6902        synchronized(this) {
6903            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6904            if (r == null) {
6905                return null;
6906            }
6907            return r.packageName;
6908        }
6909    }
6910
6911    @Override
6912    public boolean isRootVoiceInteraction(IBinder token) {
6913        synchronized(this) {
6914            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6915            if (r == null) {
6916                return false;
6917            }
6918            return r.rootVoiceInteraction;
6919        }
6920    }
6921
6922    @Override
6923    public IIntentSender getIntentSender(int type,
6924            String packageName, IBinder token, String resultWho,
6925            int requestCode, Intent[] intents, String[] resolvedTypes,
6926            int flags, Bundle bOptions, int userId) {
6927        enforceNotIsolatedCaller("getIntentSender");
6928        // Refuse possible leaked file descriptors
6929        if (intents != null) {
6930            if (intents.length < 1) {
6931                throw new IllegalArgumentException("Intents array length must be >= 1");
6932            }
6933            for (int i=0; i<intents.length; i++) {
6934                Intent intent = intents[i];
6935                if (intent != null) {
6936                    if (intent.hasFileDescriptors()) {
6937                        throw new IllegalArgumentException("File descriptors passed in Intent");
6938                    }
6939                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6940                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6941                        throw new IllegalArgumentException(
6942                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6943                    }
6944                    intents[i] = new Intent(intent);
6945                }
6946            }
6947            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6948                throw new IllegalArgumentException(
6949                        "Intent array length does not match resolvedTypes length");
6950            }
6951        }
6952        if (bOptions != null) {
6953            if (bOptions.hasFileDescriptors()) {
6954                throw new IllegalArgumentException("File descriptors passed in options");
6955            }
6956        }
6957
6958        synchronized(this) {
6959            int callingUid = Binder.getCallingUid();
6960            int origUserId = userId;
6961            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6962                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6963                    ALLOW_NON_FULL, "getIntentSender", null);
6964            if (origUserId == UserHandle.USER_CURRENT) {
6965                // We don't want to evaluate this until the pending intent is
6966                // actually executed.  However, we do want to always do the
6967                // security checking for it above.
6968                userId = UserHandle.USER_CURRENT;
6969            }
6970            try {
6971                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6972                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6973                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6974                    if (!UserHandle.isSameApp(callingUid, uid)) {
6975                        String msg = "Permission Denial: getIntentSender() from pid="
6976                            + Binder.getCallingPid()
6977                            + ", uid=" + Binder.getCallingUid()
6978                            + ", (need uid=" + uid + ")"
6979                            + " is not allowed to send as package " + packageName;
6980                        Slog.w(TAG, msg);
6981                        throw new SecurityException(msg);
6982                    }
6983                }
6984
6985                return getIntentSenderLocked(type, packageName, callingUid, userId,
6986                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6987
6988            } catch (RemoteException e) {
6989                throw new SecurityException(e);
6990            }
6991        }
6992    }
6993
6994    IIntentSender getIntentSenderLocked(int type, String packageName,
6995            int callingUid, int userId, IBinder token, String resultWho,
6996            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6997            Bundle bOptions) {
6998        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6999        ActivityRecord activity = null;
7000        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7001            activity = ActivityRecord.isInStackLocked(token);
7002            if (activity == null) {
7003                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7004                return null;
7005            }
7006            if (activity.finishing) {
7007                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7008                return null;
7009            }
7010        }
7011
7012        // We're going to be splicing together extras before sending, so we're
7013        // okay poking into any contained extras.
7014        if (intents != null) {
7015            for (int i = 0; i < intents.length; i++) {
7016                intents[i].setDefusable(true);
7017            }
7018        }
7019        Bundle.setDefusable(bOptions, true);
7020
7021        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7022        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7023        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7024        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7025                |PendingIntent.FLAG_UPDATE_CURRENT);
7026
7027        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7028                type, packageName, activity, resultWho,
7029                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7030        WeakReference<PendingIntentRecord> ref;
7031        ref = mIntentSenderRecords.get(key);
7032        PendingIntentRecord rec = ref != null ? ref.get() : null;
7033        if (rec != null) {
7034            if (!cancelCurrent) {
7035                if (updateCurrent) {
7036                    if (rec.key.requestIntent != null) {
7037                        rec.key.requestIntent.replaceExtras(intents != null ?
7038                                intents[intents.length - 1] : null);
7039                    }
7040                    if (intents != null) {
7041                        intents[intents.length-1] = rec.key.requestIntent;
7042                        rec.key.allIntents = intents;
7043                        rec.key.allResolvedTypes = resolvedTypes;
7044                    } else {
7045                        rec.key.allIntents = null;
7046                        rec.key.allResolvedTypes = null;
7047                    }
7048                }
7049                return rec;
7050            }
7051            rec.canceled = true;
7052            mIntentSenderRecords.remove(key);
7053        }
7054        if (noCreate) {
7055            return rec;
7056        }
7057        rec = new PendingIntentRecord(this, key, callingUid);
7058        mIntentSenderRecords.put(key, rec.ref);
7059        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7060            if (activity.pendingResults == null) {
7061                activity.pendingResults
7062                        = new HashSet<WeakReference<PendingIntentRecord>>();
7063            }
7064            activity.pendingResults.add(rec.ref);
7065        }
7066        return rec;
7067    }
7068
7069    @Override
7070    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7071            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7072        if (target instanceof PendingIntentRecord) {
7073            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7074                    finishedReceiver, requiredPermission, options);
7075        } else {
7076            if (intent == null) {
7077                // Weird case: someone has given us their own custom IIntentSender, and now
7078                // they have someone else trying to send to it but of course this isn't
7079                // really a PendingIntent, so there is no base Intent, and the caller isn't
7080                // supplying an Intent... but we never want to dispatch a null Intent to
7081                // a receiver, so um...  let's make something up.
7082                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7083                intent = new Intent(Intent.ACTION_MAIN);
7084            }
7085            try {
7086                target.send(code, intent, resolvedType, null, requiredPermission, options);
7087            } catch (RemoteException e) {
7088            }
7089            // Platform code can rely on getting a result back when the send is done, but if
7090            // this intent sender is from outside of the system we can't rely on it doing that.
7091            // So instead we don't give it the result receiver, and instead just directly
7092            // report the finish immediately.
7093            if (finishedReceiver != null) {
7094                try {
7095                    finishedReceiver.performReceive(intent, 0,
7096                            null, null, false, false, UserHandle.getCallingUserId());
7097                } catch (RemoteException e) {
7098                }
7099            }
7100            return 0;
7101        }
7102    }
7103
7104    /**
7105     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7106     *
7107     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7108     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7109     */
7110    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7111        if (DEBUG_WHITELISTS) {
7112            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7113                    + targetUid + ", " + duration + ")");
7114        }
7115        synchronized (mPidsSelfLocked) {
7116            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7117            if (pr == null) {
7118                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7119                return;
7120            }
7121            if (!pr.whitelistManager) {
7122                if (DEBUG_WHITELISTS) {
7123                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7124                            + callerPid + " is not allowed");
7125                }
7126                return;
7127            }
7128        }
7129
7130        final long token = Binder.clearCallingIdentity();
7131        try {
7132            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7133                    true, "pe from uid:" + callerUid);
7134        } finally {
7135            Binder.restoreCallingIdentity(token);
7136        }
7137    }
7138
7139    @Override
7140    public void cancelIntentSender(IIntentSender sender) {
7141        if (!(sender instanceof PendingIntentRecord)) {
7142            return;
7143        }
7144        synchronized(this) {
7145            PendingIntentRecord rec = (PendingIntentRecord)sender;
7146            try {
7147                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7148                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7149                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7150                    String msg = "Permission Denial: cancelIntentSender() from pid="
7151                        + Binder.getCallingPid()
7152                        + ", uid=" + Binder.getCallingUid()
7153                        + " is not allowed to cancel packges "
7154                        + rec.key.packageName;
7155                    Slog.w(TAG, msg);
7156                    throw new SecurityException(msg);
7157                }
7158            } catch (RemoteException e) {
7159                throw new SecurityException(e);
7160            }
7161            cancelIntentSenderLocked(rec, true);
7162        }
7163    }
7164
7165    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7166        rec.canceled = true;
7167        mIntentSenderRecords.remove(rec.key);
7168        if (cleanActivity && rec.key.activity != null) {
7169            rec.key.activity.pendingResults.remove(rec.ref);
7170        }
7171    }
7172
7173    @Override
7174    public String getPackageForIntentSender(IIntentSender pendingResult) {
7175        if (!(pendingResult instanceof PendingIntentRecord)) {
7176            return null;
7177        }
7178        try {
7179            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7180            return res.key.packageName;
7181        } catch (ClassCastException e) {
7182        }
7183        return null;
7184    }
7185
7186    @Override
7187    public int getUidForIntentSender(IIntentSender sender) {
7188        if (sender instanceof PendingIntentRecord) {
7189            try {
7190                PendingIntentRecord res = (PendingIntentRecord)sender;
7191                return res.uid;
7192            } catch (ClassCastException e) {
7193            }
7194        }
7195        return -1;
7196    }
7197
7198    @Override
7199    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7200        if (!(pendingResult instanceof PendingIntentRecord)) {
7201            return false;
7202        }
7203        try {
7204            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7205            if (res.key.allIntents == null) {
7206                return false;
7207            }
7208            for (int i=0; i<res.key.allIntents.length; i++) {
7209                Intent intent = res.key.allIntents[i];
7210                if (intent.getPackage() != null && intent.getComponent() != null) {
7211                    return false;
7212                }
7213            }
7214            return true;
7215        } catch (ClassCastException e) {
7216        }
7217        return false;
7218    }
7219
7220    @Override
7221    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7222        if (!(pendingResult instanceof PendingIntentRecord)) {
7223            return false;
7224        }
7225        try {
7226            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7227            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7228                return true;
7229            }
7230            return false;
7231        } catch (ClassCastException e) {
7232        }
7233        return false;
7234    }
7235
7236    @Override
7237    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7238        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7239                "getIntentForIntentSender()");
7240        if (!(pendingResult instanceof PendingIntentRecord)) {
7241            return null;
7242        }
7243        try {
7244            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7245            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7246        } catch (ClassCastException e) {
7247        }
7248        return null;
7249    }
7250
7251    @Override
7252    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7253        if (!(pendingResult instanceof PendingIntentRecord)) {
7254            return null;
7255        }
7256        try {
7257            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7258            synchronized (this) {
7259                return getTagForIntentSenderLocked(res, prefix);
7260            }
7261        } catch (ClassCastException e) {
7262        }
7263        return null;
7264    }
7265
7266    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7267        final Intent intent = res.key.requestIntent;
7268        if (intent != null) {
7269            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7270                    || res.lastTagPrefix.equals(prefix))) {
7271                return res.lastTag;
7272            }
7273            res.lastTagPrefix = prefix;
7274            final StringBuilder sb = new StringBuilder(128);
7275            if (prefix != null) {
7276                sb.append(prefix);
7277            }
7278            if (intent.getAction() != null) {
7279                sb.append(intent.getAction());
7280            } else if (intent.getComponent() != null) {
7281                intent.getComponent().appendShortString(sb);
7282            } else {
7283                sb.append("?");
7284            }
7285            return res.lastTag = sb.toString();
7286        }
7287        return null;
7288    }
7289
7290    @Override
7291    public void setProcessLimit(int max) {
7292        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7293                "setProcessLimit()");
7294        synchronized (this) {
7295            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7296            mProcessLimitOverride = max;
7297        }
7298        trimApplications();
7299    }
7300
7301    @Override
7302    public int getProcessLimit() {
7303        synchronized (this) {
7304            return mProcessLimitOverride;
7305        }
7306    }
7307
7308    void foregroundTokenDied(ForegroundToken token) {
7309        synchronized (ActivityManagerService.this) {
7310            synchronized (mPidsSelfLocked) {
7311                ForegroundToken cur
7312                    = mForegroundProcesses.get(token.pid);
7313                if (cur != token) {
7314                    return;
7315                }
7316                mForegroundProcesses.remove(token.pid);
7317                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7318                if (pr == null) {
7319                    return;
7320                }
7321                pr.forcingToForeground = null;
7322                updateProcessForegroundLocked(pr, false, false);
7323            }
7324            updateOomAdjLocked();
7325        }
7326    }
7327
7328    @Override
7329    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7330        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7331                "setProcessForeground()");
7332        synchronized(this) {
7333            boolean changed = false;
7334
7335            synchronized (mPidsSelfLocked) {
7336                ProcessRecord pr = mPidsSelfLocked.get(pid);
7337                if (pr == null && isForeground) {
7338                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7339                    return;
7340                }
7341                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7342                if (oldToken != null) {
7343                    oldToken.token.unlinkToDeath(oldToken, 0);
7344                    mForegroundProcesses.remove(pid);
7345                    if (pr != null) {
7346                        pr.forcingToForeground = null;
7347                    }
7348                    changed = true;
7349                }
7350                if (isForeground && token != null) {
7351                    ForegroundToken newToken = new ForegroundToken() {
7352                        @Override
7353                        public void binderDied() {
7354                            foregroundTokenDied(this);
7355                        }
7356                    };
7357                    newToken.pid = pid;
7358                    newToken.token = token;
7359                    try {
7360                        token.linkToDeath(newToken, 0);
7361                        mForegroundProcesses.put(pid, newToken);
7362                        pr.forcingToForeground = token;
7363                        changed = true;
7364                    } catch (RemoteException e) {
7365                        // If the process died while doing this, we will later
7366                        // do the cleanup with the process death link.
7367                    }
7368                }
7369            }
7370
7371            if (changed) {
7372                updateOomAdjLocked();
7373            }
7374        }
7375    }
7376
7377    @Override
7378    public boolean isAppForeground(int uid) throws RemoteException {
7379        synchronized (this) {
7380            UidRecord uidRec = mActiveUids.get(uid);
7381            if (uidRec == null || uidRec.idle) {
7382                return false;
7383            }
7384            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7385        }
7386    }
7387
7388    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7389    // be guarded by permission checking.
7390    int getUidState(int uid) {
7391        synchronized (this) {
7392            UidRecord uidRec = mActiveUids.get(uid);
7393            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7394        }
7395    }
7396
7397    @Override
7398    public boolean isInMultiWindowMode(IBinder token) {
7399        final long origId = Binder.clearCallingIdentity();
7400        try {
7401            synchronized(this) {
7402                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7403                if (r == null) {
7404                    return false;
7405                }
7406                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7407                return !r.task.mFullscreen;
7408            }
7409        } finally {
7410            Binder.restoreCallingIdentity(origId);
7411        }
7412    }
7413
7414    @Override
7415    public boolean isInPictureInPictureMode(IBinder token) {
7416        final long origId = Binder.clearCallingIdentity();
7417        try {
7418            synchronized(this) {
7419                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7420                if (stack == null) {
7421                    return false;
7422                }
7423                return stack.mStackId == PINNED_STACK_ID;
7424            }
7425        } finally {
7426            Binder.restoreCallingIdentity(origId);
7427        }
7428    }
7429
7430    @Override
7431    public void enterPictureInPictureMode(IBinder token) {
7432        final long origId = Binder.clearCallingIdentity();
7433        try {
7434            synchronized(this) {
7435                if (!mSupportsPictureInPicture) {
7436                    throw new IllegalStateException("enterPictureInPictureMode: "
7437                            + "Device doesn't support picture-in-picture mode.");
7438                }
7439
7440                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7441
7442                if (r == null) {
7443                    throw new IllegalStateException("enterPictureInPictureMode: "
7444                            + "Can't find activity for token=" + token);
7445                }
7446
7447                if (!r.supportsPictureInPicture()) {
7448                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7449                            + "Picture-In-Picture not supported for r=" + r);
7450                }
7451
7452                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7453                // current bounds.
7454                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7455                final Rect bounds = (pinnedStack != null)
7456                        ? pinnedStack.mBounds
7457                        : mWindowManager.getPictureInPictureDefaultBounds(DEFAULT_DISPLAY);
7458
7459                mStackSupervisor.moveActivityToPinnedStackLocked(
7460                        r, "enterPictureInPictureMode", bounds);
7461            }
7462        } finally {
7463            Binder.restoreCallingIdentity(origId);
7464        }
7465    }
7466
7467    // =========================================================
7468    // PROCESS INFO
7469    // =========================================================
7470
7471    static class ProcessInfoService extends IProcessInfoService.Stub {
7472        final ActivityManagerService mActivityManagerService;
7473        ProcessInfoService(ActivityManagerService activityManagerService) {
7474            mActivityManagerService = activityManagerService;
7475        }
7476
7477        @Override
7478        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7479            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7480                    /*in*/ pids, /*out*/ states, null);
7481        }
7482
7483        @Override
7484        public void getProcessStatesAndOomScoresFromPids(
7485                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7486            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7487                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7488        }
7489    }
7490
7491    /**
7492     * For each PID in the given input array, write the current process state
7493     * for that process into the states array, or -1 to indicate that no
7494     * process with the given PID exists. If scores array is provided, write
7495     * the oom score for the process into the scores array, with INVALID_ADJ
7496     * indicating the PID doesn't exist.
7497     */
7498    public void getProcessStatesAndOomScoresForPIDs(
7499            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7500        if (scores != null) {
7501            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7502                    "getProcessStatesAndOomScoresForPIDs()");
7503        }
7504
7505        if (pids == null) {
7506            throw new NullPointerException("pids");
7507        } else if (states == null) {
7508            throw new NullPointerException("states");
7509        } else if (pids.length != states.length) {
7510            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7511        } else if (scores != null && pids.length != scores.length) {
7512            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7513        }
7514
7515        synchronized (mPidsSelfLocked) {
7516            for (int i = 0; i < pids.length; i++) {
7517                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7518                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7519                        pr.curProcState;
7520                if (scores != null) {
7521                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7522                }
7523            }
7524        }
7525    }
7526
7527    // =========================================================
7528    // PERMISSIONS
7529    // =========================================================
7530
7531    static class PermissionController extends IPermissionController.Stub {
7532        ActivityManagerService mActivityManagerService;
7533        PermissionController(ActivityManagerService activityManagerService) {
7534            mActivityManagerService = activityManagerService;
7535        }
7536
7537        @Override
7538        public boolean checkPermission(String permission, int pid, int uid) {
7539            return mActivityManagerService.checkPermission(permission, pid,
7540                    uid) == PackageManager.PERMISSION_GRANTED;
7541        }
7542
7543        @Override
7544        public String[] getPackagesForUid(int uid) {
7545            return mActivityManagerService.mContext.getPackageManager()
7546                    .getPackagesForUid(uid);
7547        }
7548
7549        @Override
7550        public boolean isRuntimePermission(String permission) {
7551            try {
7552                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7553                        .getPermissionInfo(permission, 0);
7554                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7555                        == PermissionInfo.PROTECTION_DANGEROUS;
7556            } catch (NameNotFoundException nnfe) {
7557                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7558            }
7559            return false;
7560        }
7561    }
7562
7563    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7564        @Override
7565        public int checkComponentPermission(String permission, int pid, int uid,
7566                int owningUid, boolean exported) {
7567            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7568                    owningUid, exported);
7569        }
7570
7571        @Override
7572        public Object getAMSLock() {
7573            return ActivityManagerService.this;
7574        }
7575    }
7576
7577    /**
7578     * This can be called with or without the global lock held.
7579     */
7580    int checkComponentPermission(String permission, int pid, int uid,
7581            int owningUid, boolean exported) {
7582        if (pid == MY_PID) {
7583            return PackageManager.PERMISSION_GRANTED;
7584        }
7585        return ActivityManager.checkComponentPermission(permission, uid,
7586                owningUid, exported);
7587    }
7588
7589    /**
7590     * As the only public entry point for permissions checking, this method
7591     * can enforce the semantic that requesting a check on a null global
7592     * permission is automatically denied.  (Internally a null permission
7593     * string is used when calling {@link #checkComponentPermission} in cases
7594     * when only uid-based security is needed.)
7595     *
7596     * This can be called with or without the global lock held.
7597     */
7598    @Override
7599    public int checkPermission(String permission, int pid, int uid) {
7600        if (permission == null) {
7601            return PackageManager.PERMISSION_DENIED;
7602        }
7603        return checkComponentPermission(permission, pid, uid, -1, true);
7604    }
7605
7606    @Override
7607    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7608        if (permission == null) {
7609            return PackageManager.PERMISSION_DENIED;
7610        }
7611
7612        // We might be performing an operation on behalf of an indirect binder
7613        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7614        // client identity accordingly before proceeding.
7615        Identity tlsIdentity = sCallerIdentity.get();
7616        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7617            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7618                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7619            uid = tlsIdentity.uid;
7620            pid = tlsIdentity.pid;
7621        }
7622
7623        return checkComponentPermission(permission, pid, uid, -1, true);
7624    }
7625
7626    /**
7627     * Binder IPC calls go through the public entry point.
7628     * This can be called with or without the global lock held.
7629     */
7630    int checkCallingPermission(String permission) {
7631        return checkPermission(permission,
7632                Binder.getCallingPid(),
7633                UserHandle.getAppId(Binder.getCallingUid()));
7634    }
7635
7636    /**
7637     * This can be called with or without the global lock held.
7638     */
7639    void enforceCallingPermission(String permission, String func) {
7640        if (checkCallingPermission(permission)
7641                == PackageManager.PERMISSION_GRANTED) {
7642            return;
7643        }
7644
7645        String msg = "Permission Denial: " + func + " from pid="
7646                + Binder.getCallingPid()
7647                + ", uid=" + Binder.getCallingUid()
7648                + " requires " + permission;
7649        Slog.w(TAG, msg);
7650        throw new SecurityException(msg);
7651    }
7652
7653    /**
7654     * Determine if UID is holding permissions required to access {@link Uri} in
7655     * the given {@link ProviderInfo}. Final permission checking is always done
7656     * in {@link ContentProvider}.
7657     */
7658    private final boolean checkHoldingPermissionsLocked(
7659            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7660        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7661                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7662        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7663            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7664                    != PERMISSION_GRANTED) {
7665                return false;
7666            }
7667        }
7668        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7669    }
7670
7671    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7672            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7673        if (pi.applicationInfo.uid == uid) {
7674            return true;
7675        } else if (!pi.exported) {
7676            return false;
7677        }
7678
7679        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7680        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7681        try {
7682            // check if target holds top-level <provider> permissions
7683            if (!readMet && pi.readPermission != null && considerUidPermissions
7684                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7685                readMet = true;
7686            }
7687            if (!writeMet && pi.writePermission != null && considerUidPermissions
7688                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7689                writeMet = true;
7690            }
7691
7692            // track if unprotected read/write is allowed; any denied
7693            // <path-permission> below removes this ability
7694            boolean allowDefaultRead = pi.readPermission == null;
7695            boolean allowDefaultWrite = pi.writePermission == null;
7696
7697            // check if target holds any <path-permission> that match uri
7698            final PathPermission[] pps = pi.pathPermissions;
7699            if (pps != null) {
7700                final String path = grantUri.uri.getPath();
7701                int i = pps.length;
7702                while (i > 0 && (!readMet || !writeMet)) {
7703                    i--;
7704                    PathPermission pp = pps[i];
7705                    if (pp.match(path)) {
7706                        if (!readMet) {
7707                            final String pprperm = pp.getReadPermission();
7708                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7709                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7710                                    + ": match=" + pp.match(path)
7711                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7712                            if (pprperm != null) {
7713                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7714                                        == PERMISSION_GRANTED) {
7715                                    readMet = true;
7716                                } else {
7717                                    allowDefaultRead = false;
7718                                }
7719                            }
7720                        }
7721                        if (!writeMet) {
7722                            final String ppwperm = pp.getWritePermission();
7723                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7724                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7725                                    + ": match=" + pp.match(path)
7726                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7727                            if (ppwperm != null) {
7728                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7729                                        == PERMISSION_GRANTED) {
7730                                    writeMet = true;
7731                                } else {
7732                                    allowDefaultWrite = false;
7733                                }
7734                            }
7735                        }
7736                    }
7737                }
7738            }
7739
7740            // grant unprotected <provider> read/write, if not blocked by
7741            // <path-permission> above
7742            if (allowDefaultRead) readMet = true;
7743            if (allowDefaultWrite) writeMet = true;
7744
7745        } catch (RemoteException e) {
7746            return false;
7747        }
7748
7749        return readMet && writeMet;
7750    }
7751
7752    public int getAppStartMode(int uid, String packageName) {
7753        synchronized (this) {
7754            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7755        }
7756    }
7757
7758    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7759            boolean allowWhenForeground) {
7760        UidRecord uidRec = mActiveUids.get(uid);
7761        if (!mLenientBackgroundCheck) {
7762            if (!allowWhenForeground || uidRec == null
7763                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7764                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7765                        packageName) != AppOpsManager.MODE_ALLOWED) {
7766                    return ActivityManager.APP_START_MODE_DELAYED;
7767                }
7768            }
7769
7770        } else if (uidRec == null || uidRec.idle) {
7771            if (callingPid >= 0) {
7772                ProcessRecord proc;
7773                synchronized (mPidsSelfLocked) {
7774                    proc = mPidsSelfLocked.get(callingPid);
7775                }
7776                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7777                    // Whoever is instigating this is in the foreground, so we will allow it
7778                    // to go through.
7779                    return ActivityManager.APP_START_MODE_NORMAL;
7780                }
7781            }
7782            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7783                    != AppOpsManager.MODE_ALLOWED) {
7784                return ActivityManager.APP_START_MODE_DELAYED;
7785            }
7786        }
7787        return ActivityManager.APP_START_MODE_NORMAL;
7788    }
7789
7790    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7791        ProviderInfo pi = null;
7792        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7793        if (cpr != null) {
7794            pi = cpr.info;
7795        } else {
7796            try {
7797                pi = AppGlobals.getPackageManager().resolveContentProvider(
7798                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7799                        userHandle);
7800            } catch (RemoteException ex) {
7801            }
7802        }
7803        return pi;
7804    }
7805
7806    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7807        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7808        if (targetUris != null) {
7809            return targetUris.get(grantUri);
7810        }
7811        return null;
7812    }
7813
7814    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7815            String targetPkg, int targetUid, GrantUri grantUri) {
7816        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7817        if (targetUris == null) {
7818            targetUris = Maps.newArrayMap();
7819            mGrantedUriPermissions.put(targetUid, targetUris);
7820        }
7821
7822        UriPermission perm = targetUris.get(grantUri);
7823        if (perm == null) {
7824            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7825            targetUris.put(grantUri, perm);
7826        }
7827
7828        return perm;
7829    }
7830
7831    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7832            final int modeFlags) {
7833        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7834        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7835                : UriPermission.STRENGTH_OWNED;
7836
7837        // Root gets to do everything.
7838        if (uid == 0) {
7839            return true;
7840        }
7841
7842        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7843        if (perms == null) return false;
7844
7845        // First look for exact match
7846        final UriPermission exactPerm = perms.get(grantUri);
7847        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7848            return true;
7849        }
7850
7851        // No exact match, look for prefixes
7852        final int N = perms.size();
7853        for (int i = 0; i < N; i++) {
7854            final UriPermission perm = perms.valueAt(i);
7855            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7856                    && perm.getStrength(modeFlags) >= minStrength) {
7857                return true;
7858            }
7859        }
7860
7861        return false;
7862    }
7863
7864    /**
7865     * @param uri This uri must NOT contain an embedded userId.
7866     * @param userId The userId in which the uri is to be resolved.
7867     */
7868    @Override
7869    public int checkUriPermission(Uri uri, int pid, int uid,
7870            final int modeFlags, int userId, IBinder callerToken) {
7871        enforceNotIsolatedCaller("checkUriPermission");
7872
7873        // Another redirected-binder-call permissions check as in
7874        // {@link checkPermissionWithToken}.
7875        Identity tlsIdentity = sCallerIdentity.get();
7876        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7877            uid = tlsIdentity.uid;
7878            pid = tlsIdentity.pid;
7879        }
7880
7881        // Our own process gets to do everything.
7882        if (pid == MY_PID) {
7883            return PackageManager.PERMISSION_GRANTED;
7884        }
7885        synchronized (this) {
7886            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7887                    ? PackageManager.PERMISSION_GRANTED
7888                    : PackageManager.PERMISSION_DENIED;
7889        }
7890    }
7891
7892    /**
7893     * Check if the targetPkg can be granted permission to access uri by
7894     * the callingUid using the given modeFlags.  Throws a security exception
7895     * if callingUid is not allowed to do this.  Returns the uid of the target
7896     * if the URI permission grant should be performed; returns -1 if it is not
7897     * needed (for example targetPkg already has permission to access the URI).
7898     * If you already know the uid of the target, you can supply it in
7899     * lastTargetUid else set that to -1.
7900     */
7901    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7902            final int modeFlags, int lastTargetUid) {
7903        if (!Intent.isAccessUriMode(modeFlags)) {
7904            return -1;
7905        }
7906
7907        if (targetPkg != null) {
7908            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7909                    "Checking grant " + targetPkg + " permission to " + grantUri);
7910        }
7911
7912        final IPackageManager pm = AppGlobals.getPackageManager();
7913
7914        // If this is not a content: uri, we can't do anything with it.
7915        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7916            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7917                    "Can't grant URI permission for non-content URI: " + grantUri);
7918            return -1;
7919        }
7920
7921        final String authority = grantUri.uri.getAuthority();
7922        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7923                MATCH_DEBUG_TRIAGED_MISSING);
7924        if (pi == null) {
7925            Slog.w(TAG, "No content provider found for permission check: " +
7926                    grantUri.uri.toSafeString());
7927            return -1;
7928        }
7929
7930        int targetUid = lastTargetUid;
7931        if (targetUid < 0 && targetPkg != null) {
7932            try {
7933                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7934                        UserHandle.getUserId(callingUid));
7935                if (targetUid < 0) {
7936                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7937                            "Can't grant URI permission no uid for: " + targetPkg);
7938                    return -1;
7939                }
7940            } catch (RemoteException ex) {
7941                return -1;
7942            }
7943        }
7944
7945        if (targetUid >= 0) {
7946            // First...  does the target actually need this permission?
7947            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7948                // No need to grant the target this permission.
7949                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7950                        "Target " + targetPkg + " already has full permission to " + grantUri);
7951                return -1;
7952            }
7953        } else {
7954            // First...  there is no target package, so can anyone access it?
7955            boolean allowed = pi.exported;
7956            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7957                if (pi.readPermission != null) {
7958                    allowed = false;
7959                }
7960            }
7961            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7962                if (pi.writePermission != null) {
7963                    allowed = false;
7964                }
7965            }
7966            if (allowed) {
7967                return -1;
7968            }
7969        }
7970
7971        /* There is a special cross user grant if:
7972         * - The target is on another user.
7973         * - Apps on the current user can access the uri without any uid permissions.
7974         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7975         * grant uri permissions.
7976         */
7977        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7978                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7979                modeFlags, false /*without considering the uid permissions*/);
7980
7981        // Second...  is the provider allowing granting of URI permissions?
7982        if (!specialCrossUserGrant) {
7983            if (!pi.grantUriPermissions) {
7984                throw new SecurityException("Provider " + pi.packageName
7985                        + "/" + pi.name
7986                        + " does not allow granting of Uri permissions (uri "
7987                        + grantUri + ")");
7988            }
7989            if (pi.uriPermissionPatterns != null) {
7990                final int N = pi.uriPermissionPatterns.length;
7991                boolean allowed = false;
7992                for (int i=0; i<N; i++) {
7993                    if (pi.uriPermissionPatterns[i] != null
7994                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7995                        allowed = true;
7996                        break;
7997                    }
7998                }
7999                if (!allowed) {
8000                    throw new SecurityException("Provider " + pi.packageName
8001                            + "/" + pi.name
8002                            + " does not allow granting of permission to path of Uri "
8003                            + grantUri);
8004                }
8005            }
8006        }
8007
8008        // Third...  does the caller itself have permission to access
8009        // this uri?
8010        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8011            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8012                // Require they hold a strong enough Uri permission
8013                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8014                    throw new SecurityException("Uid " + callingUid
8015                            + " does not have permission to uri " + grantUri);
8016                }
8017            }
8018        }
8019        return targetUid;
8020    }
8021
8022    /**
8023     * @param uri This uri must NOT contain an embedded userId.
8024     * @param userId The userId in which the uri is to be resolved.
8025     */
8026    @Override
8027    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8028            final int modeFlags, int userId) {
8029        enforceNotIsolatedCaller("checkGrantUriPermission");
8030        synchronized(this) {
8031            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8032                    new GrantUri(userId, uri, false), modeFlags, -1);
8033        }
8034    }
8035
8036    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8037            final int modeFlags, UriPermissionOwner owner) {
8038        if (!Intent.isAccessUriMode(modeFlags)) {
8039            return;
8040        }
8041
8042        // So here we are: the caller has the assumed permission
8043        // to the uri, and the target doesn't.  Let's now give this to
8044        // the target.
8045
8046        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8047                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8048
8049        final String authority = grantUri.uri.getAuthority();
8050        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8051                MATCH_DEBUG_TRIAGED_MISSING);
8052        if (pi == null) {
8053            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8054            return;
8055        }
8056
8057        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8058            grantUri.prefix = true;
8059        }
8060        final UriPermission perm = findOrCreateUriPermissionLocked(
8061                pi.packageName, targetPkg, targetUid, grantUri);
8062        perm.grantModes(modeFlags, owner);
8063    }
8064
8065    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8066            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8067        if (targetPkg == null) {
8068            throw new NullPointerException("targetPkg");
8069        }
8070        int targetUid;
8071        final IPackageManager pm = AppGlobals.getPackageManager();
8072        try {
8073            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8074        } catch (RemoteException ex) {
8075            return;
8076        }
8077
8078        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8079                targetUid);
8080        if (targetUid < 0) {
8081            return;
8082        }
8083
8084        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8085                owner);
8086    }
8087
8088    static class NeededUriGrants extends ArrayList<GrantUri> {
8089        final String targetPkg;
8090        final int targetUid;
8091        final int flags;
8092
8093        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8094            this.targetPkg = targetPkg;
8095            this.targetUid = targetUid;
8096            this.flags = flags;
8097        }
8098    }
8099
8100    /**
8101     * Like checkGrantUriPermissionLocked, but takes an Intent.
8102     */
8103    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8104            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8105        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8106                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8107                + " clip=" + (intent != null ? intent.getClipData() : null)
8108                + " from " + intent + "; flags=0x"
8109                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8110
8111        if (targetPkg == null) {
8112            throw new NullPointerException("targetPkg");
8113        }
8114
8115        if (intent == null) {
8116            return null;
8117        }
8118        Uri data = intent.getData();
8119        ClipData clip = intent.getClipData();
8120        if (data == null && clip == null) {
8121            return null;
8122        }
8123        // Default userId for uris in the intent (if they don't specify it themselves)
8124        int contentUserHint = intent.getContentUserHint();
8125        if (contentUserHint == UserHandle.USER_CURRENT) {
8126            contentUserHint = UserHandle.getUserId(callingUid);
8127        }
8128        final IPackageManager pm = AppGlobals.getPackageManager();
8129        int targetUid;
8130        if (needed != null) {
8131            targetUid = needed.targetUid;
8132        } else {
8133            try {
8134                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8135                        targetUserId);
8136            } catch (RemoteException ex) {
8137                return null;
8138            }
8139            if (targetUid < 0) {
8140                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8141                        "Can't grant URI permission no uid for: " + targetPkg
8142                        + " on user " + targetUserId);
8143                return null;
8144            }
8145        }
8146        if (data != null) {
8147            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8148            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8149                    targetUid);
8150            if (targetUid > 0) {
8151                if (needed == null) {
8152                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8153                }
8154                needed.add(grantUri);
8155            }
8156        }
8157        if (clip != null) {
8158            for (int i=0; i<clip.getItemCount(); i++) {
8159                Uri uri = clip.getItemAt(i).getUri();
8160                if (uri != null) {
8161                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8162                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8163                            targetUid);
8164                    if (targetUid > 0) {
8165                        if (needed == null) {
8166                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8167                        }
8168                        needed.add(grantUri);
8169                    }
8170                } else {
8171                    Intent clipIntent = clip.getItemAt(i).getIntent();
8172                    if (clipIntent != null) {
8173                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8174                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8175                        if (newNeeded != null) {
8176                            needed = newNeeded;
8177                        }
8178                    }
8179                }
8180            }
8181        }
8182
8183        return needed;
8184    }
8185
8186    /**
8187     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8188     */
8189    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8190            UriPermissionOwner owner) {
8191        if (needed != null) {
8192            for (int i=0; i<needed.size(); i++) {
8193                GrantUri grantUri = needed.get(i);
8194                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8195                        grantUri, needed.flags, owner);
8196            }
8197        }
8198    }
8199
8200    void grantUriPermissionFromIntentLocked(int callingUid,
8201            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8202        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8203                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8204        if (needed == null) {
8205            return;
8206        }
8207
8208        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8209    }
8210
8211    /**
8212     * @param uri This uri must NOT contain an embedded userId.
8213     * @param userId The userId in which the uri is to be resolved.
8214     */
8215    @Override
8216    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8217            final int modeFlags, int userId) {
8218        enforceNotIsolatedCaller("grantUriPermission");
8219        GrantUri grantUri = new GrantUri(userId, uri, false);
8220        synchronized(this) {
8221            final ProcessRecord r = getRecordForAppLocked(caller);
8222            if (r == null) {
8223                throw new SecurityException("Unable to find app for caller "
8224                        + caller
8225                        + " when granting permission to uri " + grantUri);
8226            }
8227            if (targetPkg == null) {
8228                throw new IllegalArgumentException("null target");
8229            }
8230            if (grantUri == null) {
8231                throw new IllegalArgumentException("null uri");
8232            }
8233
8234            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8235                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8236                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8237                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8238
8239            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8240                    UserHandle.getUserId(r.uid));
8241        }
8242    }
8243
8244    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8245        if (perm.modeFlags == 0) {
8246            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8247                    perm.targetUid);
8248            if (perms != null) {
8249                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8250                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8251
8252                perms.remove(perm.uri);
8253                if (perms.isEmpty()) {
8254                    mGrantedUriPermissions.remove(perm.targetUid);
8255                }
8256            }
8257        }
8258    }
8259
8260    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8261        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8262                "Revoking all granted permissions to " + grantUri);
8263
8264        final IPackageManager pm = AppGlobals.getPackageManager();
8265        final String authority = grantUri.uri.getAuthority();
8266        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8267                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8268        if (pi == null) {
8269            Slog.w(TAG, "No content provider found for permission revoke: "
8270                    + grantUri.toSafeString());
8271            return;
8272        }
8273
8274        // Does the caller have this permission on the URI?
8275        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8276            // If they don't have direct access to the URI, then revoke any
8277            // ownerless URI permissions that have been granted to them.
8278            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8279            if (perms != null) {
8280                boolean persistChanged = false;
8281                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8282                    final UriPermission perm = it.next();
8283                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8284                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8285                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8286                                "Revoking non-owned " + perm.targetUid
8287                                + " permission to " + perm.uri);
8288                        persistChanged |= perm.revokeModes(
8289                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8290                        if (perm.modeFlags == 0) {
8291                            it.remove();
8292                        }
8293                    }
8294                }
8295                if (perms.isEmpty()) {
8296                    mGrantedUriPermissions.remove(callingUid);
8297                }
8298                if (persistChanged) {
8299                    schedulePersistUriGrants();
8300                }
8301            }
8302            return;
8303        }
8304
8305        boolean persistChanged = false;
8306
8307        // Go through all of the permissions and remove any that match.
8308        int N = mGrantedUriPermissions.size();
8309        for (int i = 0; i < N; i++) {
8310            final int targetUid = mGrantedUriPermissions.keyAt(i);
8311            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8312
8313            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8314                final UriPermission perm = it.next();
8315                if (perm.uri.sourceUserId == grantUri.sourceUserId
8316                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8317                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8318                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8319                    persistChanged |= perm.revokeModes(
8320                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8321                    if (perm.modeFlags == 0) {
8322                        it.remove();
8323                    }
8324                }
8325            }
8326
8327            if (perms.isEmpty()) {
8328                mGrantedUriPermissions.remove(targetUid);
8329                N--;
8330                i--;
8331            }
8332        }
8333
8334        if (persistChanged) {
8335            schedulePersistUriGrants();
8336        }
8337    }
8338
8339    /**
8340     * @param uri This uri must NOT contain an embedded userId.
8341     * @param userId The userId in which the uri is to be resolved.
8342     */
8343    @Override
8344    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8345            int userId) {
8346        enforceNotIsolatedCaller("revokeUriPermission");
8347        synchronized(this) {
8348            final ProcessRecord r = getRecordForAppLocked(caller);
8349            if (r == null) {
8350                throw new SecurityException("Unable to find app for caller "
8351                        + caller
8352                        + " when revoking permission to uri " + uri);
8353            }
8354            if (uri == null) {
8355                Slog.w(TAG, "revokeUriPermission: null uri");
8356                return;
8357            }
8358
8359            if (!Intent.isAccessUriMode(modeFlags)) {
8360                return;
8361            }
8362
8363            final String authority = uri.getAuthority();
8364            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8365                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8366            if (pi == null) {
8367                Slog.w(TAG, "No content provider found for permission revoke: "
8368                        + uri.toSafeString());
8369                return;
8370            }
8371
8372            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8373        }
8374    }
8375
8376    /**
8377     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8378     * given package.
8379     *
8380     * @param packageName Package name to match, or {@code null} to apply to all
8381     *            packages.
8382     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8383     *            to all users.
8384     * @param persistable If persistable grants should be removed.
8385     */
8386    private void removeUriPermissionsForPackageLocked(
8387            String packageName, int userHandle, boolean persistable) {
8388        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8389            throw new IllegalArgumentException("Must narrow by either package or user");
8390        }
8391
8392        boolean persistChanged = false;
8393
8394        int N = mGrantedUriPermissions.size();
8395        for (int i = 0; i < N; i++) {
8396            final int targetUid = mGrantedUriPermissions.keyAt(i);
8397            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8398
8399            // Only inspect grants matching user
8400            if (userHandle == UserHandle.USER_ALL
8401                    || userHandle == UserHandle.getUserId(targetUid)) {
8402                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8403                    final UriPermission perm = it.next();
8404
8405                    // Only inspect grants matching package
8406                    if (packageName == null || perm.sourcePkg.equals(packageName)
8407                            || perm.targetPkg.equals(packageName)) {
8408                        persistChanged |= perm.revokeModes(persistable
8409                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8410
8411                        // Only remove when no modes remain; any persisted grants
8412                        // will keep this alive.
8413                        if (perm.modeFlags == 0) {
8414                            it.remove();
8415                        }
8416                    }
8417                }
8418
8419                if (perms.isEmpty()) {
8420                    mGrantedUriPermissions.remove(targetUid);
8421                    N--;
8422                    i--;
8423                }
8424            }
8425        }
8426
8427        if (persistChanged) {
8428            schedulePersistUriGrants();
8429        }
8430    }
8431
8432    @Override
8433    public IBinder newUriPermissionOwner(String name) {
8434        enforceNotIsolatedCaller("newUriPermissionOwner");
8435        synchronized(this) {
8436            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8437            return owner.getExternalTokenLocked();
8438        }
8439    }
8440
8441    @Override
8442    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8443        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8444        synchronized(this) {
8445            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8446            if (r == null) {
8447                throw new IllegalArgumentException("Activity does not exist; token="
8448                        + activityToken);
8449            }
8450            return r.getUriPermissionsLocked().getExternalTokenLocked();
8451        }
8452    }
8453    /**
8454     * @param uri This uri must NOT contain an embedded userId.
8455     * @param sourceUserId The userId in which the uri is to be resolved.
8456     * @param targetUserId The userId of the app that receives the grant.
8457     */
8458    @Override
8459    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8460            final int modeFlags, int sourceUserId, int targetUserId) {
8461        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8462                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8463                "grantUriPermissionFromOwner", null);
8464        synchronized(this) {
8465            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8466            if (owner == null) {
8467                throw new IllegalArgumentException("Unknown owner: " + token);
8468            }
8469            if (fromUid != Binder.getCallingUid()) {
8470                if (Binder.getCallingUid() != Process.myUid()) {
8471                    // Only system code can grant URI permissions on behalf
8472                    // of other users.
8473                    throw new SecurityException("nice try");
8474                }
8475            }
8476            if (targetPkg == null) {
8477                throw new IllegalArgumentException("null target");
8478            }
8479            if (uri == null) {
8480                throw new IllegalArgumentException("null uri");
8481            }
8482
8483            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8484                    modeFlags, owner, targetUserId);
8485        }
8486    }
8487
8488    /**
8489     * @param uri This uri must NOT contain an embedded userId.
8490     * @param userId The userId in which the uri is to be resolved.
8491     */
8492    @Override
8493    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8494        synchronized(this) {
8495            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8496            if (owner == null) {
8497                throw new IllegalArgumentException("Unknown owner: " + token);
8498            }
8499
8500            if (uri == null) {
8501                owner.removeUriPermissionsLocked(mode);
8502            } else {
8503                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8504                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8505            }
8506        }
8507    }
8508
8509    private void schedulePersistUriGrants() {
8510        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8511            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8512                    10 * DateUtils.SECOND_IN_MILLIS);
8513        }
8514    }
8515
8516    private void writeGrantedUriPermissions() {
8517        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8518
8519        // Snapshot permissions so we can persist without lock
8520        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8521        synchronized (this) {
8522            final int size = mGrantedUriPermissions.size();
8523            for (int i = 0; i < size; i++) {
8524                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8525                for (UriPermission perm : perms.values()) {
8526                    if (perm.persistedModeFlags != 0) {
8527                        persist.add(perm.snapshot());
8528                    }
8529                }
8530            }
8531        }
8532
8533        FileOutputStream fos = null;
8534        try {
8535            fos = mGrantFile.startWrite();
8536
8537            XmlSerializer out = new FastXmlSerializer();
8538            out.setOutput(fos, StandardCharsets.UTF_8.name());
8539            out.startDocument(null, true);
8540            out.startTag(null, TAG_URI_GRANTS);
8541            for (UriPermission.Snapshot perm : persist) {
8542                out.startTag(null, TAG_URI_GRANT);
8543                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8544                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8545                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8546                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8547                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8548                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8549                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8550                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8551                out.endTag(null, TAG_URI_GRANT);
8552            }
8553            out.endTag(null, TAG_URI_GRANTS);
8554            out.endDocument();
8555
8556            mGrantFile.finishWrite(fos);
8557        } catch (IOException e) {
8558            if (fos != null) {
8559                mGrantFile.failWrite(fos);
8560            }
8561        }
8562    }
8563
8564    private void readGrantedUriPermissionsLocked() {
8565        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8566
8567        final long now = System.currentTimeMillis();
8568
8569        FileInputStream fis = null;
8570        try {
8571            fis = mGrantFile.openRead();
8572            final XmlPullParser in = Xml.newPullParser();
8573            in.setInput(fis, StandardCharsets.UTF_8.name());
8574
8575            int type;
8576            while ((type = in.next()) != END_DOCUMENT) {
8577                final String tag = in.getName();
8578                if (type == START_TAG) {
8579                    if (TAG_URI_GRANT.equals(tag)) {
8580                        final int sourceUserId;
8581                        final int targetUserId;
8582                        final int userHandle = readIntAttribute(in,
8583                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8584                        if (userHandle != UserHandle.USER_NULL) {
8585                            // For backwards compatibility.
8586                            sourceUserId = userHandle;
8587                            targetUserId = userHandle;
8588                        } else {
8589                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8590                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8591                        }
8592                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8593                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8594                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8595                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8596                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8597                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8598
8599                        // Sanity check that provider still belongs to source package
8600                        // Both direct boot aware and unaware packages are fine as we
8601                        // will do filtering at query time to avoid multiple parsing.
8602                        final ProviderInfo pi = getProviderInfoLocked(
8603                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8604                                        | MATCH_DIRECT_BOOT_UNAWARE);
8605                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8606                            int targetUid = -1;
8607                            try {
8608                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8609                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8610                            } catch (RemoteException e) {
8611                            }
8612                            if (targetUid != -1) {
8613                                final UriPermission perm = findOrCreateUriPermissionLocked(
8614                                        sourcePkg, targetPkg, targetUid,
8615                                        new GrantUri(sourceUserId, uri, prefix));
8616                                perm.initPersistedModes(modeFlags, createdTime);
8617                            }
8618                        } else {
8619                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8620                                    + " but instead found " + pi);
8621                        }
8622                    }
8623                }
8624            }
8625        } catch (FileNotFoundException e) {
8626            // Missing grants is okay
8627        } catch (IOException e) {
8628            Slog.wtf(TAG, "Failed reading Uri grants", e);
8629        } catch (XmlPullParserException e) {
8630            Slog.wtf(TAG, "Failed reading Uri grants", e);
8631        } finally {
8632            IoUtils.closeQuietly(fis);
8633        }
8634    }
8635
8636    /**
8637     * @param uri This uri must NOT contain an embedded userId.
8638     * @param userId The userId in which the uri is to be resolved.
8639     */
8640    @Override
8641    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8642        enforceNotIsolatedCaller("takePersistableUriPermission");
8643
8644        Preconditions.checkFlagsArgument(modeFlags,
8645                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8646
8647        synchronized (this) {
8648            final int callingUid = Binder.getCallingUid();
8649            boolean persistChanged = false;
8650            GrantUri grantUri = new GrantUri(userId, uri, false);
8651
8652            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8653                    new GrantUri(userId, uri, false));
8654            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8655                    new GrantUri(userId, uri, true));
8656
8657            final boolean exactValid = (exactPerm != null)
8658                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8659            final boolean prefixValid = (prefixPerm != null)
8660                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8661
8662            if (!(exactValid || prefixValid)) {
8663                throw new SecurityException("No persistable permission grants found for UID "
8664                        + callingUid + " and Uri " + grantUri.toSafeString());
8665            }
8666
8667            if (exactValid) {
8668                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8669            }
8670            if (prefixValid) {
8671                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8672            }
8673
8674            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8675
8676            if (persistChanged) {
8677                schedulePersistUriGrants();
8678            }
8679        }
8680    }
8681
8682    /**
8683     * @param uri This uri must NOT contain an embedded userId.
8684     * @param userId The userId in which the uri is to be resolved.
8685     */
8686    @Override
8687    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8688        enforceNotIsolatedCaller("releasePersistableUriPermission");
8689
8690        Preconditions.checkFlagsArgument(modeFlags,
8691                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8692
8693        synchronized (this) {
8694            final int callingUid = Binder.getCallingUid();
8695            boolean persistChanged = false;
8696
8697            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8698                    new GrantUri(userId, uri, false));
8699            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8700                    new GrantUri(userId, uri, true));
8701            if (exactPerm == null && prefixPerm == null) {
8702                throw new SecurityException("No permission grants found for UID " + callingUid
8703                        + " and Uri " + uri.toSafeString());
8704            }
8705
8706            if (exactPerm != null) {
8707                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8708                removeUriPermissionIfNeededLocked(exactPerm);
8709            }
8710            if (prefixPerm != null) {
8711                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8712                removeUriPermissionIfNeededLocked(prefixPerm);
8713            }
8714
8715            if (persistChanged) {
8716                schedulePersistUriGrants();
8717            }
8718        }
8719    }
8720
8721    /**
8722     * Prune any older {@link UriPermission} for the given UID until outstanding
8723     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8724     *
8725     * @return if any mutations occured that require persisting.
8726     */
8727    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8728        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8729        if (perms == null) return false;
8730        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8731
8732        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8733        for (UriPermission perm : perms.values()) {
8734            if (perm.persistedModeFlags != 0) {
8735                persisted.add(perm);
8736            }
8737        }
8738
8739        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8740        if (trimCount <= 0) return false;
8741
8742        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8743        for (int i = 0; i < trimCount; i++) {
8744            final UriPermission perm = persisted.get(i);
8745
8746            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8747                    "Trimming grant created at " + perm.persistedCreateTime);
8748
8749            perm.releasePersistableModes(~0);
8750            removeUriPermissionIfNeededLocked(perm);
8751        }
8752
8753        return true;
8754    }
8755
8756    @Override
8757    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8758            String packageName, boolean incoming) {
8759        enforceNotIsolatedCaller("getPersistedUriPermissions");
8760        Preconditions.checkNotNull(packageName, "packageName");
8761
8762        final int callingUid = Binder.getCallingUid();
8763        final int callingUserId = UserHandle.getUserId(callingUid);
8764        final IPackageManager pm = AppGlobals.getPackageManager();
8765        try {
8766            final int packageUid = pm.getPackageUid(packageName,
8767                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8768            if (packageUid != callingUid) {
8769                throw new SecurityException(
8770                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8771            }
8772        } catch (RemoteException e) {
8773            throw new SecurityException("Failed to verify package name ownership");
8774        }
8775
8776        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8777        synchronized (this) {
8778            if (incoming) {
8779                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8780                        callingUid);
8781                if (perms == null) {
8782                    Slog.w(TAG, "No permission grants found for " + packageName);
8783                } else {
8784                    for (UriPermission perm : perms.values()) {
8785                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8786                            result.add(perm.buildPersistedPublicApiObject());
8787                        }
8788                    }
8789                }
8790            } else {
8791                final int size = mGrantedUriPermissions.size();
8792                for (int i = 0; i < size; i++) {
8793                    final ArrayMap<GrantUri, UriPermission> perms =
8794                            mGrantedUriPermissions.valueAt(i);
8795                    for (UriPermission perm : perms.values()) {
8796                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8797                            result.add(perm.buildPersistedPublicApiObject());
8798                        }
8799                    }
8800                }
8801            }
8802        }
8803        return new ParceledListSlice<android.content.UriPermission>(result);
8804    }
8805
8806    @Override
8807    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8808            String packageName, int userId) {
8809        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8810                "getGrantedUriPermissions");
8811
8812        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8813        synchronized (this) {
8814            final int size = mGrantedUriPermissions.size();
8815            for (int i = 0; i < size; i++) {
8816                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8817                for (UriPermission perm : perms.values()) {
8818                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8819                            && perm.persistedModeFlags != 0) {
8820                        result.add(perm.buildPersistedPublicApiObject());
8821                    }
8822                }
8823            }
8824        }
8825        return new ParceledListSlice<android.content.UriPermission>(result);
8826    }
8827
8828    @Override
8829    public void clearGrantedUriPermissions(String packageName, int userId) {
8830        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8831                "clearGrantedUriPermissions");
8832        removeUriPermissionsForPackageLocked(packageName, userId, true);
8833    }
8834
8835    @Override
8836    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8837        synchronized (this) {
8838            ProcessRecord app =
8839                who != null ? getRecordForAppLocked(who) : null;
8840            if (app == null) return;
8841
8842            Message msg = Message.obtain();
8843            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8844            msg.obj = app;
8845            msg.arg1 = waiting ? 1 : 0;
8846            mUiHandler.sendMessage(msg);
8847        }
8848    }
8849
8850    @Override
8851    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8852        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8853        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8854        outInfo.availMem = Process.getFreeMemory();
8855        outInfo.totalMem = Process.getTotalMemory();
8856        outInfo.threshold = homeAppMem;
8857        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8858        outInfo.hiddenAppThreshold = cachedAppMem;
8859        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8860                ProcessList.SERVICE_ADJ);
8861        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8862                ProcessList.VISIBLE_APP_ADJ);
8863        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8864                ProcessList.FOREGROUND_APP_ADJ);
8865    }
8866
8867    // =========================================================
8868    // TASK MANAGEMENT
8869    // =========================================================
8870
8871    @Override
8872    public List<IBinder> getAppTasks(String callingPackage) {
8873        int callingUid = Binder.getCallingUid();
8874        long ident = Binder.clearCallingIdentity();
8875
8876        synchronized(this) {
8877            ArrayList<IBinder> list = new ArrayList<IBinder>();
8878            try {
8879                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8880
8881                final int N = mRecentTasks.size();
8882                for (int i = 0; i < N; i++) {
8883                    TaskRecord tr = mRecentTasks.get(i);
8884                    // Skip tasks that do not match the caller.  We don't need to verify
8885                    // callingPackage, because we are also limiting to callingUid and know
8886                    // that will limit to the correct security sandbox.
8887                    if (tr.effectiveUid != callingUid) {
8888                        continue;
8889                    }
8890                    Intent intent = tr.getBaseIntent();
8891                    if (intent == null ||
8892                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8893                        continue;
8894                    }
8895                    ActivityManager.RecentTaskInfo taskInfo =
8896                            createRecentTaskInfoFromTaskRecord(tr);
8897                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8898                    list.add(taskImpl.asBinder());
8899                }
8900            } finally {
8901                Binder.restoreCallingIdentity(ident);
8902            }
8903            return list;
8904        }
8905    }
8906
8907    @Override
8908    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8909        final int callingUid = Binder.getCallingUid();
8910        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8911
8912        synchronized(this) {
8913            if (DEBUG_ALL) Slog.v(
8914                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8915
8916            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8917                    callingUid);
8918
8919            // TODO: Improve with MRU list from all ActivityStacks.
8920            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8921        }
8922
8923        return list;
8924    }
8925
8926    /**
8927     * Creates a new RecentTaskInfo from a TaskRecord.
8928     */
8929    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8930        // Update the task description to reflect any changes in the task stack
8931        tr.updateTaskDescription();
8932
8933        // Compose the recent task info
8934        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8935        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8936        rti.persistentId = tr.taskId;
8937        rti.baseIntent = new Intent(tr.getBaseIntent());
8938        rti.origActivity = tr.origActivity;
8939        rti.realActivity = tr.realActivity;
8940        rti.description = tr.lastDescription;
8941        rti.stackId = tr.getStackId();
8942        rti.userId = tr.userId;
8943        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8944        rti.firstActiveTime = tr.firstActiveTime;
8945        rti.lastActiveTime = tr.lastActiveTime;
8946        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8947        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8948        rti.numActivities = 0;
8949        if (tr.mBounds != null) {
8950            rti.bounds = new Rect(tr.mBounds);
8951        }
8952        rti.isDockable = tr.canGoInDockedStack();
8953        rti.resizeMode = tr.mResizeMode;
8954
8955        ActivityRecord base = null;
8956        ActivityRecord top = null;
8957        ActivityRecord tmp;
8958
8959        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8960            tmp = tr.mActivities.get(i);
8961            if (tmp.finishing) {
8962                continue;
8963            }
8964            base = tmp;
8965            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8966                top = base;
8967            }
8968            rti.numActivities++;
8969        }
8970
8971        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8972        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8973
8974        return rti;
8975    }
8976
8977    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8978        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8979                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8980        if (!allowed) {
8981            if (checkPermission(android.Manifest.permission.GET_TASKS,
8982                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8983                // Temporary compatibility: some existing apps on the system image may
8984                // still be requesting the old permission and not switched to the new
8985                // one; if so, we'll still allow them full access.  This means we need
8986                // to see if they are holding the old permission and are a system app.
8987                try {
8988                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8989                        allowed = true;
8990                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8991                                + " is using old GET_TASKS but privileged; allowing");
8992                    }
8993                } catch (RemoteException e) {
8994                }
8995            }
8996        }
8997        if (!allowed) {
8998            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8999                    + " does not hold REAL_GET_TASKS; limiting output");
9000        }
9001        return allowed;
9002    }
9003
9004    @Override
9005    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9006            int userId) {
9007        final int callingUid = Binder.getCallingUid();
9008        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9009                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9010
9011        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9012        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9013        synchronized (this) {
9014            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9015                    callingUid);
9016            final boolean detailed = checkCallingPermission(
9017                    android.Manifest.permission.GET_DETAILED_TASKS)
9018                    == PackageManager.PERMISSION_GRANTED;
9019
9020            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9021                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9022                return ParceledListSlice.emptyList();
9023            }
9024            mRecentTasks.loadUserRecentsLocked(userId);
9025
9026            final int recentsCount = mRecentTasks.size();
9027            ArrayList<ActivityManager.RecentTaskInfo> res =
9028                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9029
9030            final Set<Integer> includedUsers;
9031            if (includeProfiles) {
9032                includedUsers = mUserController.getProfileIds(userId);
9033            } else {
9034                includedUsers = new HashSet<>();
9035            }
9036            includedUsers.add(Integer.valueOf(userId));
9037
9038            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9039                TaskRecord tr = mRecentTasks.get(i);
9040                // Only add calling user or related users recent tasks
9041                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9042                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9043                    continue;
9044                }
9045
9046                if (tr.realActivitySuspended) {
9047                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9048                    continue;
9049                }
9050
9051                // Return the entry if desired by the caller.  We always return
9052                // the first entry, because callers always expect this to be the
9053                // foreground app.  We may filter others if the caller has
9054                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9055                // we should exclude the entry.
9056
9057                if (i == 0
9058                        || withExcluded
9059                        || (tr.intent == null)
9060                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9061                                == 0)) {
9062                    if (!allowed) {
9063                        // If the caller doesn't have the GET_TASKS permission, then only
9064                        // allow them to see a small subset of tasks -- their own and home.
9065                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9066                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9067                            continue;
9068                        }
9069                    }
9070                    final ActivityStack stack = tr.getStack();
9071                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9072                        if (stack != null && stack.isHomeStack()) {
9073                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9074                                    "Skipping, home stack task: " + tr);
9075                            continue;
9076                        }
9077                    }
9078                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9079                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9080                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9081                                    "Skipping, top task in docked stack: " + tr);
9082                            continue;
9083                        }
9084                    }
9085                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9086                        if (stack != null && stack.isPinnedStack()) {
9087                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9088                                    "Skipping, pinned stack task: " + tr);
9089                            continue;
9090                        }
9091                    }
9092                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9093                        // Don't include auto remove tasks that are finished or finishing.
9094                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9095                                "Skipping, auto-remove without activity: " + tr);
9096                        continue;
9097                    }
9098                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9099                            && !tr.isAvailable) {
9100                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9101                                "Skipping, unavail real act: " + tr);
9102                        continue;
9103                    }
9104
9105                    if (!tr.mUserSetupComplete) {
9106                        // Don't include task launched while user is not done setting-up.
9107                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9108                                "Skipping, user setup not complete: " + tr);
9109                        continue;
9110                    }
9111
9112                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9113                    if (!detailed) {
9114                        rti.baseIntent.replaceExtras((Bundle)null);
9115                    }
9116
9117                    res.add(rti);
9118                    maxNum--;
9119                }
9120            }
9121            return new ParceledListSlice<>(res);
9122        }
9123    }
9124
9125    @Override
9126    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9127        synchronized (this) {
9128            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9129                    "getTaskThumbnail()");
9130            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9131                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9132            if (tr != null) {
9133                return tr.getTaskThumbnailLocked();
9134            }
9135        }
9136        return null;
9137    }
9138
9139    @Override
9140    public int addAppTask(IBinder activityToken, Intent intent,
9141            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9142        final int callingUid = Binder.getCallingUid();
9143        final long callingIdent = Binder.clearCallingIdentity();
9144
9145        try {
9146            synchronized (this) {
9147                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9148                if (r == null) {
9149                    throw new IllegalArgumentException("Activity does not exist; token="
9150                            + activityToken);
9151                }
9152                ComponentName comp = intent.getComponent();
9153                if (comp == null) {
9154                    throw new IllegalArgumentException("Intent " + intent
9155                            + " must specify explicit component");
9156                }
9157                if (thumbnail.getWidth() != mThumbnailWidth
9158                        || thumbnail.getHeight() != mThumbnailHeight) {
9159                    throw new IllegalArgumentException("Bad thumbnail size: got "
9160                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9161                            + mThumbnailWidth + "x" + mThumbnailHeight);
9162                }
9163                if (intent.getSelector() != null) {
9164                    intent.setSelector(null);
9165                }
9166                if (intent.getSourceBounds() != null) {
9167                    intent.setSourceBounds(null);
9168                }
9169                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9170                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9171                        // The caller has added this as an auto-remove task...  that makes no
9172                        // sense, so turn off auto-remove.
9173                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9174                    }
9175                }
9176                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9177                    mLastAddedTaskActivity = null;
9178                }
9179                ActivityInfo ainfo = mLastAddedTaskActivity;
9180                if (ainfo == null) {
9181                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9182                            comp, 0, UserHandle.getUserId(callingUid));
9183                    if (ainfo.applicationInfo.uid != callingUid) {
9184                        throw new SecurityException(
9185                                "Can't add task for another application: target uid="
9186                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9187                    }
9188                }
9189
9190                TaskRecord task = new TaskRecord(this,
9191                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9192                        ainfo, intent, description, new TaskThumbnailInfo());
9193
9194                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9195                if (trimIdx >= 0) {
9196                    // If this would have caused a trim, then we'll abort because that
9197                    // means it would be added at the end of the list but then just removed.
9198                    return INVALID_TASK_ID;
9199                }
9200
9201                final int N = mRecentTasks.size();
9202                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9203                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9204                    tr.removedFromRecents();
9205                }
9206
9207                task.inRecents = true;
9208                mRecentTasks.add(task);
9209                r.getStack().addTask(task, false, "addAppTask");
9210
9211                task.setLastThumbnailLocked(thumbnail);
9212                task.freeLastThumbnail();
9213                return task.taskId;
9214            }
9215        } finally {
9216            Binder.restoreCallingIdentity(callingIdent);
9217        }
9218    }
9219
9220    @Override
9221    public Point getAppTaskThumbnailSize() {
9222        synchronized (this) {
9223            return new Point(mThumbnailWidth,  mThumbnailHeight);
9224        }
9225    }
9226
9227    @Override
9228    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9229        synchronized (this) {
9230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9231            if (r != null) {
9232                r.setTaskDescription(td);
9233                r.task.updateTaskDescription();
9234                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9235            }
9236        }
9237    }
9238
9239    @Override
9240    public void setTaskResizeable(int taskId, int resizeableMode) {
9241        synchronized (this) {
9242            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9243                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9244            if (task == null) {
9245                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9246                return;
9247            }
9248            if (task.mResizeMode != resizeableMode) {
9249                task.mResizeMode = resizeableMode;
9250                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9251                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9252                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9253            }
9254        }
9255    }
9256
9257    @Override
9258    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9259        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9260        long ident = Binder.clearCallingIdentity();
9261        try {
9262            synchronized (this) {
9263                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9264                if (task == null) {
9265                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9266                    return;
9267                }
9268                // Place the task in the right stack if it isn't there already based on
9269                // the requested bounds.
9270                // The stack transition logic is:
9271                // - a null bounds on a freeform task moves that task to fullscreen
9272                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9273                //   that task to freeform
9274                // - otherwise the task is not moved
9275                int stackId = task.getStackId();
9276                if (!StackId.isTaskResizeAllowed(stackId)) {
9277                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9278                }
9279                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9280                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9281                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9282                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9283                }
9284                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9285                if (stackId != task.getStackId()) {
9286                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9287                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9288                    preserveWindow = false;
9289                }
9290
9291                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9292                        false /* deferResume */);
9293            }
9294        } finally {
9295            Binder.restoreCallingIdentity(ident);
9296        }
9297    }
9298
9299    @Override
9300    public Rect getTaskBounds(int taskId) {
9301        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9302        long ident = Binder.clearCallingIdentity();
9303        Rect rect = new Rect();
9304        try {
9305            synchronized (this) {
9306                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9307                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9308                if (task == null) {
9309                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9310                    return rect;
9311                }
9312                if (task.getStack() != null) {
9313                    // Return the bounds from window manager since it will be adjusted for various
9314                    // things like the presense of a docked stack for tasks that aren't resizeable.
9315                    mWindowManager.getTaskBounds(task.taskId, rect);
9316                } else {
9317                    // Task isn't in window manager yet since it isn't associated with a stack.
9318                    // Return the persist value from activity manager
9319                    if (task.mBounds != null) {
9320                        rect.set(task.mBounds);
9321                    } else if (task.mLastNonFullscreenBounds != null) {
9322                        rect.set(task.mLastNonFullscreenBounds);
9323                    }
9324                }
9325            }
9326        } finally {
9327            Binder.restoreCallingIdentity(ident);
9328        }
9329        return rect;
9330    }
9331
9332    @Override
9333    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9334        if (userId != UserHandle.getCallingUserId()) {
9335            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9336                    "getTaskDescriptionIcon");
9337        }
9338        final File passedIconFile = new File(filePath);
9339        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9340                passedIconFile.getName());
9341        if (!legitIconFile.getPath().equals(filePath)
9342                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9343            throw new IllegalArgumentException("Bad file path: " + filePath
9344                    + " passed for userId " + userId);
9345        }
9346        return mRecentTasks.getTaskDescriptionIcon(filePath);
9347    }
9348
9349    @Override
9350    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9351            throws RemoteException {
9352        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9353        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9354                activityOptions.getCustomInPlaceResId() == 0) {
9355            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9356                    "with valid animation");
9357        }
9358        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9359        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9360                activityOptions.getCustomInPlaceResId());
9361        mWindowManager.executeAppTransition();
9362    }
9363
9364    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9365            boolean removeFromRecents) {
9366        if (removeFromRecents) {
9367            mRecentTasks.remove(tr);
9368            tr.removedFromRecents();
9369        }
9370        ComponentName component = tr.getBaseIntent().getComponent();
9371        if (component == null) {
9372            Slog.w(TAG, "No component for base intent of task: " + tr);
9373            return;
9374        }
9375
9376        // Find any running services associated with this app and stop if needed.
9377        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9378
9379        if (!killProcess) {
9380            return;
9381        }
9382
9383        // Determine if the process(es) for this task should be killed.
9384        final String pkg = component.getPackageName();
9385        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9386        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9387        for (int i = 0; i < pmap.size(); i++) {
9388
9389            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9390            for (int j = 0; j < uids.size(); j++) {
9391                ProcessRecord proc = uids.valueAt(j);
9392                if (proc.userId != tr.userId) {
9393                    // Don't kill process for a different user.
9394                    continue;
9395                }
9396                if (proc == mHomeProcess) {
9397                    // Don't kill the home process along with tasks from the same package.
9398                    continue;
9399                }
9400                if (!proc.pkgList.containsKey(pkg)) {
9401                    // Don't kill process that is not associated with this task.
9402                    continue;
9403                }
9404
9405                for (int k = 0; k < proc.activities.size(); k++) {
9406                    TaskRecord otherTask = proc.activities.get(k).task;
9407                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9408                        // Don't kill process(es) that has an activity in a different task that is
9409                        // also in recents.
9410                        return;
9411                    }
9412                }
9413
9414                if (proc.foregroundServices) {
9415                    // Don't kill process(es) with foreground service.
9416                    return;
9417                }
9418
9419                // Add process to kill list.
9420                procsToKill.add(proc);
9421            }
9422        }
9423
9424        // Kill the running processes.
9425        for (int i = 0; i < procsToKill.size(); i++) {
9426            ProcessRecord pr = procsToKill.get(i);
9427            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9428                    && pr.curReceivers.isEmpty()) {
9429                pr.kill("remove task", true);
9430            } else {
9431                // We delay killing processes that are not in the background or running a receiver.
9432                pr.waitingToKill = "remove task";
9433            }
9434        }
9435    }
9436
9437    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9438        // Remove all tasks with activities in the specified package from the list of recent tasks
9439        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9440            TaskRecord tr = mRecentTasks.get(i);
9441            if (tr.userId != userId) continue;
9442
9443            ComponentName cn = tr.intent.getComponent();
9444            if (cn != null && cn.getPackageName().equals(packageName)) {
9445                // If the package name matches, remove the task.
9446                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9447            }
9448        }
9449    }
9450
9451    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9452            int userId) {
9453
9454        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9455            TaskRecord tr = mRecentTasks.get(i);
9456            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9457                continue;
9458            }
9459
9460            ComponentName cn = tr.intent.getComponent();
9461            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9462                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9463            if (sameComponent) {
9464                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9465            }
9466        }
9467    }
9468
9469    /**
9470     * Removes the task with the specified task id.
9471     *
9472     * @param taskId Identifier of the task to be removed.
9473     * @param killProcess Kill any process associated with the task if possible.
9474     * @param removeFromRecents Whether to also remove the task from recents.
9475     * @return Returns true if the given task was found and removed.
9476     */
9477    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9478            boolean removeFromRecents) {
9479        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9480                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9481        if (tr != null) {
9482            tr.removeTaskActivitiesLocked();
9483            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9484            if (tr.isPersistable) {
9485                notifyTaskPersisterLocked(null, true);
9486            }
9487            return true;
9488        }
9489        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9490        return false;
9491    }
9492
9493    @Override
9494    public void removeStack(int stackId) {
9495        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9496        if (stackId == HOME_STACK_ID) {
9497            throw new IllegalArgumentException("Removing home stack is not allowed.");
9498        }
9499
9500        synchronized (this) {
9501            final long ident = Binder.clearCallingIdentity();
9502            try {
9503                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9504                if (stack == null) {
9505                    return;
9506                }
9507                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9508                for (int i = tasks.size() - 1; i >= 0; i--) {
9509                    removeTaskByIdLocked(
9510                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9511                }
9512            } finally {
9513                Binder.restoreCallingIdentity(ident);
9514            }
9515        }
9516    }
9517
9518    @Override
9519    public void moveStackToDisplay(int stackId, int displayId) {
9520        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
9521
9522        synchronized (this) {
9523            final long ident = Binder.clearCallingIdentity();
9524            try {
9525                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
9526                        + " to displayId=" + displayId);
9527                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId);
9528            } finally {
9529                Binder.restoreCallingIdentity(ident);
9530            }
9531        }
9532    }
9533
9534    @Override
9535    public boolean removeTask(int taskId) {
9536        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9537        synchronized (this) {
9538            final long ident = Binder.clearCallingIdentity();
9539            try {
9540                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9541            } finally {
9542                Binder.restoreCallingIdentity(ident);
9543            }
9544        }
9545    }
9546
9547    /**
9548     * TODO: Add mController hook
9549     */
9550    @Override
9551    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9552        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9553
9554        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9555        synchronized(this) {
9556            moveTaskToFrontLocked(taskId, flags, bOptions);
9557        }
9558    }
9559
9560    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9561        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9562
9563        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9564                Binder.getCallingUid(), -1, -1, "Task to front")) {
9565            ActivityOptions.abort(options);
9566            return;
9567        }
9568        final long origId = Binder.clearCallingIdentity();
9569        try {
9570            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9571            if (task == null) {
9572                Slog.d(TAG, "Could not find task for id: "+ taskId);
9573                return;
9574            }
9575            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9576                mStackSupervisor.showLockTaskToast();
9577                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9578                return;
9579            }
9580            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9581            if (prev != null && prev.isRecentsActivity()) {
9582                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9583            }
9584            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9585                    false /* forceNonResizable */);
9586        } finally {
9587            Binder.restoreCallingIdentity(origId);
9588        }
9589        ActivityOptions.abort(options);
9590    }
9591
9592    /**
9593     * Moves an activity, and all of the other activities within the same task, to the bottom
9594     * of the history stack.  The activity's order within the task is unchanged.
9595     *
9596     * @param token A reference to the activity we wish to move
9597     * @param nonRoot If false then this only works if the activity is the root
9598     *                of a task; if true it will work for any activity in a task.
9599     * @return Returns true if the move completed, false if not.
9600     */
9601    @Override
9602    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9603        enforceNotIsolatedCaller("moveActivityTaskToBack");
9604        synchronized(this) {
9605            final long origId = Binder.clearCallingIdentity();
9606            try {
9607                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9608                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9609                if (task != null) {
9610                    if (mStackSupervisor.isLockedTask(task)) {
9611                        mStackSupervisor.showLockTaskToast();
9612                        return false;
9613                    }
9614                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9615                }
9616            } finally {
9617                Binder.restoreCallingIdentity(origId);
9618            }
9619        }
9620        return false;
9621    }
9622
9623    @Override
9624    public void moveTaskBackwards(int task) {
9625        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9626                "moveTaskBackwards()");
9627
9628        synchronized(this) {
9629            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9630                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9631                return;
9632            }
9633            final long origId = Binder.clearCallingIdentity();
9634            moveTaskBackwardsLocked(task);
9635            Binder.restoreCallingIdentity(origId);
9636        }
9637    }
9638
9639    private final void moveTaskBackwardsLocked(int task) {
9640        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9641    }
9642
9643    @Override
9644    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9645            IActivityContainerCallback callback) throws RemoteException {
9646        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9647        synchronized (this) {
9648            if (parentActivityToken == null) {
9649                throw new IllegalArgumentException("parent token must not be null");
9650            }
9651            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9652            if (r == null) {
9653                return null;
9654            }
9655            if (callback == null) {
9656                throw new IllegalArgumentException("callback must not be null");
9657            }
9658            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9659        }
9660    }
9661
9662    @Override
9663    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9664        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9665        synchronized (this) {
9666            final int stackId = mStackSupervisor.getNextStackId();
9667            final ActivityStack stack =
9668                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9669            if (stack == null) {
9670                return null;
9671            }
9672            return stack.mActivityContainer;
9673        }
9674    }
9675
9676    @Override
9677    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9678        synchronized (this) {
9679            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9680            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9681                return stack.mActivityContainer.getDisplayId();
9682            }
9683            return DEFAULT_DISPLAY;
9684        }
9685    }
9686
9687    @Override
9688    public int getActivityStackId(IBinder token) throws RemoteException {
9689        synchronized (this) {
9690            ActivityStack stack = ActivityRecord.getStackLocked(token);
9691            if (stack == null) {
9692                return INVALID_STACK_ID;
9693            }
9694            return stack.mStackId;
9695        }
9696    }
9697
9698    @Override
9699    public void exitFreeformMode(IBinder token) throws RemoteException {
9700        synchronized (this) {
9701            long ident = Binder.clearCallingIdentity();
9702            try {
9703                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9704                if (r == null) {
9705                    throw new IllegalArgumentException(
9706                            "exitFreeformMode: No activity record matching token=" + token);
9707                }
9708                final ActivityStack stack = r.getStackLocked(token);
9709                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9710                    throw new IllegalStateException(
9711                            "exitFreeformMode: You can only go fullscreen from freeform.");
9712                }
9713                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9714                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9715                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9716            } finally {
9717                Binder.restoreCallingIdentity(ident);
9718            }
9719        }
9720    }
9721
9722    @Override
9723    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9724        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9725        if (stackId == HOME_STACK_ID) {
9726            throw new IllegalArgumentException(
9727                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9728        }
9729        synchronized (this) {
9730            long ident = Binder.clearCallingIdentity();
9731            try {
9732                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9733                        + " to stackId=" + stackId + " toTop=" + toTop);
9734                if (stackId == DOCKED_STACK_ID) {
9735                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9736                            null /* initialBounds */);
9737                }
9738                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9739                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9740                if (result && stackId == DOCKED_STACK_ID) {
9741                    // If task moved to docked stack - show recents if needed.
9742                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9743                            "moveTaskToDockedStack");
9744                }
9745            } finally {
9746                Binder.restoreCallingIdentity(ident);
9747            }
9748        }
9749    }
9750
9751    @Override
9752    public void swapDockedAndFullscreenStack() throws RemoteException {
9753        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9754        synchronized (this) {
9755            long ident = Binder.clearCallingIdentity();
9756            try {
9757                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9758                        FULLSCREEN_WORKSPACE_STACK_ID);
9759                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9760                        : null;
9761                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9762                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9763                        : null;
9764                if (topTask == null || tasks == null || tasks.size() == 0) {
9765                    Slog.w(TAG,
9766                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9767                    return;
9768                }
9769
9770                // TODO: App transition
9771                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9772
9773                // Defer the resume so resume/pausing while moving stacks is dangerous.
9774                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9775                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9776                        ANIMATE, true /* deferResume */);
9777                final int size = tasks.size();
9778                for (int i = 0; i < size; i++) {
9779                    final int id = tasks.get(i).taskId;
9780                    if (id == topTask.taskId) {
9781                        continue;
9782                    }
9783                    mStackSupervisor.moveTaskToStackLocked(id,
9784                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9785                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9786                }
9787
9788                // Because we deferred the resume, to avoid conflicts with stack switches while
9789                // resuming, we need to do it after all the tasks are moved.
9790                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9791                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9792
9793                mWindowManager.executeAppTransition();
9794            } finally {
9795                Binder.restoreCallingIdentity(ident);
9796            }
9797        }
9798    }
9799
9800    /**
9801     * Moves the input task to the docked stack.
9802     *
9803     * @param taskId Id of task to move.
9804     * @param createMode The mode the docked stack should be created in if it doesn't exist
9805     *                   already. See
9806     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9807     *                   and
9808     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9809     * @param toTop If the task and stack should be moved to the top.
9810     * @param animate Whether we should play an animation for the moving the task
9811     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9812     *                      docked stack. Pass {@code null} to use default bounds.
9813     */
9814    @Override
9815    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9816            Rect initialBounds, boolean moveHomeStackFront) {
9817        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9818        synchronized (this) {
9819            long ident = Binder.clearCallingIdentity();
9820            try {
9821                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9822                        + " to createMode=" + createMode + " toTop=" + toTop);
9823                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9824                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9825                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9826                        animate, DEFER_RESUME);
9827                if (moved) {
9828                    if (moveHomeStackFront) {
9829                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9830                    }
9831                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9832                }
9833                return moved;
9834            } finally {
9835                Binder.restoreCallingIdentity(ident);
9836            }
9837        }
9838    }
9839
9840    /**
9841     * Moves the top activity in the input stackId to the pinned stack.
9842     *
9843     * @param stackId Id of stack to move the top activity to pinned stack.
9844     * @param bounds Bounds to use for pinned stack.
9845     *
9846     * @return True if the top activity of the input stack was successfully moved to the pinned
9847     *          stack.
9848     */
9849    @Override
9850    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9851        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9852        synchronized (this) {
9853            if (!mSupportsPictureInPicture) {
9854                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9855                        + "Device doesn't support picture-in-pciture mode");
9856            }
9857
9858            long ident = Binder.clearCallingIdentity();
9859            try {
9860                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9861            } finally {
9862                Binder.restoreCallingIdentity(ident);
9863            }
9864        }
9865    }
9866
9867    @Override
9868    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9869            boolean preserveWindows, boolean animate, int animationDuration) {
9870        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9871        long ident = Binder.clearCallingIdentity();
9872        try {
9873            synchronized (this) {
9874                if (animate) {
9875                    if (stackId == PINNED_STACK_ID) {
9876                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9877                    } else {
9878                        throw new IllegalArgumentException("Stack: " + stackId
9879                                + " doesn't support animated resize.");
9880                    }
9881                } else {
9882                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9883                            null /* tempTaskInsetBounds */, preserveWindows,
9884                            allowResizeInDockedMode, !DEFER_RESUME);
9885                }
9886            }
9887        } finally {
9888            Binder.restoreCallingIdentity(ident);
9889        }
9890    }
9891
9892    @Override
9893    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9894            Rect tempDockedTaskInsetBounds,
9895            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9896        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9897                "resizeDockedStack()");
9898        long ident = Binder.clearCallingIdentity();
9899        try {
9900            synchronized (this) {
9901                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9902                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9903                        PRESERVE_WINDOWS);
9904            }
9905        } finally {
9906            Binder.restoreCallingIdentity(ident);
9907        }
9908    }
9909
9910    @Override
9911    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9912        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9913                "resizePinnedStack()");
9914        final long ident = Binder.clearCallingIdentity();
9915        try {
9916            synchronized (this) {
9917                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9918            }
9919        } finally {
9920            Binder.restoreCallingIdentity(ident);
9921        }
9922    }
9923
9924    @Override
9925    public void positionTaskInStack(int taskId, int stackId, int position) {
9926        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9927        if (stackId == HOME_STACK_ID) {
9928            throw new IllegalArgumentException(
9929                    "positionTaskInStack: Attempt to change the position of task "
9930                    + taskId + " in/to home stack");
9931        }
9932        synchronized (this) {
9933            long ident = Binder.clearCallingIdentity();
9934            try {
9935                if (DEBUG_STACK) Slog.d(TAG_STACK,
9936                        "positionTaskInStack: positioning task=" + taskId
9937                        + " in stackId=" + stackId + " at position=" + position);
9938                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9939            } finally {
9940                Binder.restoreCallingIdentity(ident);
9941            }
9942        }
9943    }
9944
9945    @Override
9946    public List<StackInfo> getAllStackInfos() {
9947        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9948        long ident = Binder.clearCallingIdentity();
9949        try {
9950            synchronized (this) {
9951                return mStackSupervisor.getAllStackInfosLocked();
9952            }
9953        } finally {
9954            Binder.restoreCallingIdentity(ident);
9955        }
9956    }
9957
9958    @Override
9959    public StackInfo getStackInfo(int stackId) {
9960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9961        long ident = Binder.clearCallingIdentity();
9962        try {
9963            synchronized (this) {
9964                return mStackSupervisor.getStackInfoLocked(stackId);
9965            }
9966        } finally {
9967            Binder.restoreCallingIdentity(ident);
9968        }
9969    }
9970
9971    @Override
9972    public boolean isInHomeStack(int taskId) {
9973        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9974        long ident = Binder.clearCallingIdentity();
9975        try {
9976            synchronized (this) {
9977                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9978                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9979                final ActivityStack stack = tr != null ? tr.getStack() : null;
9980                return stack != null && stack.isHomeStack();
9981            }
9982        } finally {
9983            Binder.restoreCallingIdentity(ident);
9984        }
9985    }
9986
9987    @Override
9988    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9989        synchronized(this) {
9990            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9991        }
9992    }
9993
9994    @Override
9995    public void updateDeviceOwner(String packageName) {
9996        final int callingUid = Binder.getCallingUid();
9997        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9998            throw new SecurityException("updateDeviceOwner called from non-system process");
9999        }
10000        synchronized (this) {
10001            mDeviceOwnerName = packageName;
10002        }
10003    }
10004
10005    @Override
10006    public void updateLockTaskPackages(int userId, String[] packages) {
10007        final int callingUid = Binder.getCallingUid();
10008        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10009            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10010                    "updateLockTaskPackages()");
10011        }
10012        synchronized (this) {
10013            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10014                    Arrays.toString(packages));
10015            mLockTaskPackages.put(userId, packages);
10016            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10017        }
10018    }
10019
10020
10021    void startLockTaskModeLocked(TaskRecord task) {
10022        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10023        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10024            return;
10025        }
10026
10027        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10028        // is initiated by system after the pinning request was shown and locked mode is initiated
10029        // by an authorized app directly
10030        final int callingUid = Binder.getCallingUid();
10031        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10032        long ident = Binder.clearCallingIdentity();
10033        try {
10034            if (!isSystemInitiated) {
10035                task.mLockTaskUid = callingUid;
10036                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10037                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10038                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10039                    StatusBarManagerInternal statusBarManager =
10040                            LocalServices.getService(StatusBarManagerInternal.class);
10041                    if (statusBarManager != null) {
10042                        statusBarManager.showScreenPinningRequest(task.taskId);
10043                    }
10044                    return;
10045                }
10046
10047                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10048                if (stack == null || task != stack.topTask()) {
10049                    throw new IllegalArgumentException("Invalid task, not in foreground");
10050                }
10051            }
10052            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10053                    "Locking fully");
10054            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10055                    ActivityManager.LOCK_TASK_MODE_PINNED :
10056                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10057                    "startLockTask", true);
10058        } finally {
10059            Binder.restoreCallingIdentity(ident);
10060        }
10061    }
10062
10063    @Override
10064    public void startLockTaskModeById(int taskId) {
10065        synchronized (this) {
10066            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10067            if (task != null) {
10068                startLockTaskModeLocked(task);
10069            }
10070        }
10071    }
10072
10073    @Override
10074    public void startLockTaskModeByToken(IBinder token) {
10075        synchronized (this) {
10076            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10077            if (r == null) {
10078                return;
10079            }
10080            final TaskRecord task = r.task;
10081            if (task != null) {
10082                startLockTaskModeLocked(task);
10083            }
10084        }
10085    }
10086
10087    @Override
10088    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10089        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10090        // This makes inner call to look as if it was initiated by system.
10091        long ident = Binder.clearCallingIdentity();
10092        try {
10093            synchronized (this) {
10094                startLockTaskModeById(taskId);
10095            }
10096        } finally {
10097            Binder.restoreCallingIdentity(ident);
10098        }
10099    }
10100
10101    @Override
10102    public void stopLockTaskMode() {
10103        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10104        if (lockTask == null) {
10105            // Our work here is done.
10106            return;
10107        }
10108
10109        final int callingUid = Binder.getCallingUid();
10110        final int lockTaskUid = lockTask.mLockTaskUid;
10111        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10112        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10113            // Done.
10114            return;
10115        } else {
10116            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10117            // It is possible lockTaskMode was started by the system process because
10118            // android:lockTaskMode is set to a locking value in the application manifest
10119            // instead of the app calling startLockTaskMode. In this case
10120            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10121            // {@link TaskRecord.effectiveUid} instead. Also caller with
10122            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10123            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10124                    && callingUid != lockTaskUid
10125                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10126                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10127                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10128            }
10129        }
10130        long ident = Binder.clearCallingIdentity();
10131        try {
10132            Log.d(TAG, "stopLockTaskMode");
10133            // Stop lock task
10134            synchronized (this) {
10135                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10136                        "stopLockTask", true);
10137            }
10138            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10139            if (tm != null) {
10140                tm.showInCallScreen(false);
10141            }
10142        } finally {
10143            Binder.restoreCallingIdentity(ident);
10144        }
10145    }
10146
10147    /**
10148     * This API should be called by SystemUI only when user perform certain action to dismiss
10149     * lock task mode. We should only dismiss pinned lock task mode in this case.
10150     */
10151    @Override
10152    public void stopSystemLockTaskMode() throws RemoteException {
10153        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10154            stopLockTaskMode();
10155        } else {
10156            mStackSupervisor.showLockTaskToast();
10157        }
10158    }
10159
10160    @Override
10161    public boolean isInLockTaskMode() {
10162        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10163    }
10164
10165    @Override
10166    public int getLockTaskModeState() {
10167        synchronized (this) {
10168            return mStackSupervisor.getLockTaskModeState();
10169        }
10170    }
10171
10172    @Override
10173    public void showLockTaskEscapeMessage(IBinder token) {
10174        synchronized (this) {
10175            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10176            if (r == null) {
10177                return;
10178            }
10179            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10180        }
10181    }
10182
10183    // =========================================================
10184    // CONTENT PROVIDERS
10185    // =========================================================
10186
10187    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10188        List<ProviderInfo> providers = null;
10189        try {
10190            providers = AppGlobals.getPackageManager()
10191                    .queryContentProviders(app.processName, app.uid,
10192                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10193                                    | MATCH_DEBUG_TRIAGED_MISSING)
10194                    .getList();
10195        } catch (RemoteException ex) {
10196        }
10197        if (DEBUG_MU) Slog.v(TAG_MU,
10198                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10199        int userId = app.userId;
10200        if (providers != null) {
10201            int N = providers.size();
10202            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10203            for (int i=0; i<N; i++) {
10204                // TODO: keep logic in sync with installEncryptionUnawareProviders
10205                ProviderInfo cpi =
10206                    (ProviderInfo)providers.get(i);
10207                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10208                        cpi.name, cpi.flags);
10209                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10210                    // This is a singleton provider, but a user besides the
10211                    // default user is asking to initialize a process it runs
10212                    // in...  well, no, it doesn't actually run in this process,
10213                    // it runs in the process of the default user.  Get rid of it.
10214                    providers.remove(i);
10215                    N--;
10216                    i--;
10217                    continue;
10218                }
10219
10220                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10221                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10222                if (cpr == null) {
10223                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10224                    mProviderMap.putProviderByClass(comp, cpr);
10225                }
10226                if (DEBUG_MU) Slog.v(TAG_MU,
10227                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10228                app.pubProviders.put(cpi.name, cpr);
10229                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10230                    // Don't add this if it is a platform component that is marked
10231                    // to run in multiple processes, because this is actually
10232                    // part of the framework so doesn't make sense to track as a
10233                    // separate apk in the process.
10234                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10235                            mProcessStats);
10236                }
10237                notifyPackageUse(cpi.applicationInfo.packageName,
10238                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10239            }
10240        }
10241        return providers;
10242    }
10243
10244    /**
10245     * Check if {@link ProcessRecord} has a possible chance at accessing the
10246     * given {@link ProviderInfo}. Final permission checking is always done
10247     * in {@link ContentProvider}.
10248     */
10249    private final String checkContentProviderPermissionLocked(
10250            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10251        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10252        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10253        boolean checkedGrants = false;
10254        if (checkUser) {
10255            // Looking for cross-user grants before enforcing the typical cross-users permissions
10256            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10257            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10258                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10259                    return null;
10260                }
10261                checkedGrants = true;
10262            }
10263            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10264                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10265            if (userId != tmpTargetUserId) {
10266                // When we actually went to determine the final targer user ID, this ended
10267                // up different than our initial check for the authority.  This is because
10268                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10269                // SELF.  So we need to re-check the grants again.
10270                checkedGrants = false;
10271            }
10272        }
10273        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10274                cpi.applicationInfo.uid, cpi.exported)
10275                == PackageManager.PERMISSION_GRANTED) {
10276            return null;
10277        }
10278        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10279                cpi.applicationInfo.uid, cpi.exported)
10280                == PackageManager.PERMISSION_GRANTED) {
10281            return null;
10282        }
10283
10284        PathPermission[] pps = cpi.pathPermissions;
10285        if (pps != null) {
10286            int i = pps.length;
10287            while (i > 0) {
10288                i--;
10289                PathPermission pp = pps[i];
10290                String pprperm = pp.getReadPermission();
10291                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10292                        cpi.applicationInfo.uid, cpi.exported)
10293                        == PackageManager.PERMISSION_GRANTED) {
10294                    return null;
10295                }
10296                String ppwperm = pp.getWritePermission();
10297                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10298                        cpi.applicationInfo.uid, cpi.exported)
10299                        == PackageManager.PERMISSION_GRANTED) {
10300                    return null;
10301                }
10302            }
10303        }
10304        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10305            return null;
10306        }
10307
10308        String msg;
10309        if (!cpi.exported) {
10310            msg = "Permission Denial: opening provider " + cpi.name
10311                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10312                    + ", uid=" + callingUid + ") that is not exported from uid "
10313                    + cpi.applicationInfo.uid;
10314        } else {
10315            msg = "Permission Denial: opening provider " + cpi.name
10316                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10317                    + ", uid=" + callingUid + ") requires "
10318                    + cpi.readPermission + " or " + cpi.writePermission;
10319        }
10320        Slog.w(TAG, msg);
10321        return msg;
10322    }
10323
10324    /**
10325     * Returns if the ContentProvider has granted a uri to callingUid
10326     */
10327    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10328        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10329        if (perms != null) {
10330            for (int i=perms.size()-1; i>=0; i--) {
10331                GrantUri grantUri = perms.keyAt(i);
10332                if (grantUri.sourceUserId == userId || !checkUser) {
10333                    if (matchesProvider(grantUri.uri, cpi)) {
10334                        return true;
10335                    }
10336                }
10337            }
10338        }
10339        return false;
10340    }
10341
10342    /**
10343     * Returns true if the uri authority is one of the authorities specified in the provider.
10344     */
10345    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10346        String uriAuth = uri.getAuthority();
10347        String cpiAuth = cpi.authority;
10348        if (cpiAuth.indexOf(';') == -1) {
10349            return cpiAuth.equals(uriAuth);
10350        }
10351        String[] cpiAuths = cpiAuth.split(";");
10352        int length = cpiAuths.length;
10353        for (int i = 0; i < length; i++) {
10354            if (cpiAuths[i].equals(uriAuth)) return true;
10355        }
10356        return false;
10357    }
10358
10359    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10360            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10361        if (r != null) {
10362            for (int i=0; i<r.conProviders.size(); i++) {
10363                ContentProviderConnection conn = r.conProviders.get(i);
10364                if (conn.provider == cpr) {
10365                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10366                            "Adding provider requested by "
10367                            + r.processName + " from process "
10368                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10369                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10370                    if (stable) {
10371                        conn.stableCount++;
10372                        conn.numStableIncs++;
10373                    } else {
10374                        conn.unstableCount++;
10375                        conn.numUnstableIncs++;
10376                    }
10377                    return conn;
10378                }
10379            }
10380            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10381            if (stable) {
10382                conn.stableCount = 1;
10383                conn.numStableIncs = 1;
10384            } else {
10385                conn.unstableCount = 1;
10386                conn.numUnstableIncs = 1;
10387            }
10388            cpr.connections.add(conn);
10389            r.conProviders.add(conn);
10390            startAssociationLocked(r.uid, r.processName, r.curProcState,
10391                    cpr.uid, cpr.name, cpr.info.processName);
10392            return conn;
10393        }
10394        cpr.addExternalProcessHandleLocked(externalProcessToken);
10395        return null;
10396    }
10397
10398    boolean decProviderCountLocked(ContentProviderConnection conn,
10399            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10400        if (conn != null) {
10401            cpr = conn.provider;
10402            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10403                    "Removing provider requested by "
10404                    + conn.client.processName + " from process "
10405                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10406                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10407            if (stable) {
10408                conn.stableCount--;
10409            } else {
10410                conn.unstableCount--;
10411            }
10412            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10413                cpr.connections.remove(conn);
10414                conn.client.conProviders.remove(conn);
10415                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10416                    // The client is more important than last activity -- note the time this
10417                    // is happening, so we keep the old provider process around a bit as last
10418                    // activity to avoid thrashing it.
10419                    if (cpr.proc != null) {
10420                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10421                    }
10422                }
10423                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10424                return true;
10425            }
10426            return false;
10427        }
10428        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10429        return false;
10430    }
10431
10432    private void checkTime(long startTime, String where) {
10433        long now = SystemClock.uptimeMillis();
10434        if ((now-startTime) > 50) {
10435            // If we are taking more than 50ms, log about it.
10436            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10437        }
10438    }
10439
10440    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10441            PROC_SPACE_TERM,
10442            PROC_SPACE_TERM|PROC_PARENS,
10443            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10444    };
10445
10446    private final long[] mProcessStateStatsLongs = new long[1];
10447
10448    boolean isProcessAliveLocked(ProcessRecord proc) {
10449        if (proc.procStatFile == null) {
10450            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10451        }
10452        mProcessStateStatsLongs[0] = 0;
10453        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10454                mProcessStateStatsLongs, null)) {
10455            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10456            return false;
10457        }
10458        final long state = mProcessStateStatsLongs[0];
10459        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10460                + (char)state);
10461        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10462    }
10463
10464    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10465            String name, IBinder token, boolean stable, int userId) {
10466        ContentProviderRecord cpr;
10467        ContentProviderConnection conn = null;
10468        ProviderInfo cpi = null;
10469
10470        synchronized(this) {
10471            long startTime = SystemClock.uptimeMillis();
10472
10473            ProcessRecord r = null;
10474            if (caller != null) {
10475                r = getRecordForAppLocked(caller);
10476                if (r == null) {
10477                    throw new SecurityException(
10478                            "Unable to find app for caller " + caller
10479                          + " (pid=" + Binder.getCallingPid()
10480                          + ") when getting content provider " + name);
10481                }
10482            }
10483
10484            boolean checkCrossUser = true;
10485
10486            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10487
10488            // First check if this content provider has been published...
10489            cpr = mProviderMap.getProviderByName(name, userId);
10490            // If that didn't work, check if it exists for user 0 and then
10491            // verify that it's a singleton provider before using it.
10492            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10493                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10494                if (cpr != null) {
10495                    cpi = cpr.info;
10496                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10497                            cpi.name, cpi.flags)
10498                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10499                        userId = UserHandle.USER_SYSTEM;
10500                        checkCrossUser = false;
10501                    } else {
10502                        cpr = null;
10503                        cpi = null;
10504                    }
10505                }
10506            }
10507
10508            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10509            if (providerRunning) {
10510                cpi = cpr.info;
10511                String msg;
10512                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10513                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10514                        != null) {
10515                    throw new SecurityException(msg);
10516                }
10517                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10518
10519                if (r != null && cpr.canRunHere(r)) {
10520                    // This provider has been published or is in the process
10521                    // of being published...  but it is also allowed to run
10522                    // in the caller's process, so don't make a connection
10523                    // and just let the caller instantiate its own instance.
10524                    ContentProviderHolder holder = cpr.newHolder(null);
10525                    // don't give caller the provider object, it needs
10526                    // to make its own.
10527                    holder.provider = null;
10528                    return holder;
10529                }
10530
10531                final long origId = Binder.clearCallingIdentity();
10532
10533                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10534
10535                // In this case the provider instance already exists, so we can
10536                // return it right away.
10537                conn = incProviderCountLocked(r, cpr, token, stable);
10538                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10539                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10540                        // If this is a perceptible app accessing the provider,
10541                        // make sure to count it as being accessed and thus
10542                        // back up on the LRU list.  This is good because
10543                        // content providers are often expensive to start.
10544                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10545                        updateLruProcessLocked(cpr.proc, false, null);
10546                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10547                    }
10548                }
10549
10550                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10551                final int verifiedAdj = cpr.proc.verifiedAdj;
10552                boolean success = updateOomAdjLocked(cpr.proc);
10553                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10554                // if the process has been successfully adjusted.  So to reduce races with
10555                // it, we will check whether the process still exists.  Note that this doesn't
10556                // completely get rid of races with LMK killing the process, but should make
10557                // them much smaller.
10558                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10559                    success = false;
10560                }
10561                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10562                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10563                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10564                // NOTE: there is still a race here where a signal could be
10565                // pending on the process even though we managed to update its
10566                // adj level.  Not sure what to do about this, but at least
10567                // the race is now smaller.
10568                if (!success) {
10569                    // Uh oh...  it looks like the provider's process
10570                    // has been killed on us.  We need to wait for a new
10571                    // process to be started, and make sure its death
10572                    // doesn't kill our process.
10573                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10574                            + " is crashing; detaching " + r);
10575                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10576                    checkTime(startTime, "getContentProviderImpl: before appDied");
10577                    appDiedLocked(cpr.proc);
10578                    checkTime(startTime, "getContentProviderImpl: after appDied");
10579                    if (!lastRef) {
10580                        // This wasn't the last ref our process had on
10581                        // the provider...  we have now been killed, bail.
10582                        return null;
10583                    }
10584                    providerRunning = false;
10585                    conn = null;
10586                } else {
10587                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10588                }
10589
10590                Binder.restoreCallingIdentity(origId);
10591            }
10592
10593            if (!providerRunning) {
10594                try {
10595                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10596                    cpi = AppGlobals.getPackageManager().
10597                        resolveContentProvider(name,
10598                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10599                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10600                } catch (RemoteException ex) {
10601                }
10602                if (cpi == null) {
10603                    return null;
10604                }
10605                // If the provider is a singleton AND
10606                // (it's a call within the same user || the provider is a
10607                // privileged app)
10608                // Then allow connecting to the singleton provider
10609                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10610                        cpi.name, cpi.flags)
10611                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10612                if (singleton) {
10613                    userId = UserHandle.USER_SYSTEM;
10614                }
10615                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10616                checkTime(startTime, "getContentProviderImpl: got app info for user");
10617
10618                String msg;
10619                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10620                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10621                        != null) {
10622                    throw new SecurityException(msg);
10623                }
10624                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10625
10626                if (!mProcessesReady
10627                        && !cpi.processName.equals("system")) {
10628                    // If this content provider does not run in the system
10629                    // process, and the system is not yet ready to run other
10630                    // processes, then fail fast instead of hanging.
10631                    throw new IllegalArgumentException(
10632                            "Attempt to launch content provider before system ready");
10633                }
10634
10635                // Make sure that the user who owns this provider is running.  If not,
10636                // we don't want to allow it to run.
10637                if (!mUserController.isUserRunningLocked(userId, 0)) {
10638                    Slog.w(TAG, "Unable to launch app "
10639                            + cpi.applicationInfo.packageName + "/"
10640                            + cpi.applicationInfo.uid + " for provider "
10641                            + name + ": user " + userId + " is stopped");
10642                    return null;
10643                }
10644
10645                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10646                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10647                cpr = mProviderMap.getProviderByClass(comp, userId);
10648                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10649                final boolean firstClass = cpr == null;
10650                if (firstClass) {
10651                    final long ident = Binder.clearCallingIdentity();
10652
10653                    // If permissions need a review before any of the app components can run,
10654                    // we return no provider and launch a review activity if the calling app
10655                    // is in the foreground.
10656                    if (mPermissionReviewRequired) {
10657                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10658                            return null;
10659                        }
10660                    }
10661
10662                    try {
10663                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10664                        ApplicationInfo ai =
10665                            AppGlobals.getPackageManager().
10666                                getApplicationInfo(
10667                                        cpi.applicationInfo.packageName,
10668                                        STOCK_PM_FLAGS, userId);
10669                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10670                        if (ai == null) {
10671                            Slog.w(TAG, "No package info for content provider "
10672                                    + cpi.name);
10673                            return null;
10674                        }
10675                        ai = getAppInfoForUser(ai, userId);
10676                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10677                    } catch (RemoteException ex) {
10678                        // pm is in same process, this will never happen.
10679                    } finally {
10680                        Binder.restoreCallingIdentity(ident);
10681                    }
10682                }
10683
10684                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10685
10686                if (r != null && cpr.canRunHere(r)) {
10687                    // If this is a multiprocess provider, then just return its
10688                    // info and allow the caller to instantiate it.  Only do
10689                    // this if the provider is the same user as the caller's
10690                    // process, or can run as root (so can be in any process).
10691                    return cpr.newHolder(null);
10692                }
10693
10694                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10695                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10696                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10697
10698                // This is single process, and our app is now connecting to it.
10699                // See if we are already in the process of launching this
10700                // provider.
10701                final int N = mLaunchingProviders.size();
10702                int i;
10703                for (i = 0; i < N; i++) {
10704                    if (mLaunchingProviders.get(i) == cpr) {
10705                        break;
10706                    }
10707                }
10708
10709                // If the provider is not already being launched, then get it
10710                // started.
10711                if (i >= N) {
10712                    final long origId = Binder.clearCallingIdentity();
10713
10714                    try {
10715                        // Content provider is now in use, its package can't be stopped.
10716                        try {
10717                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10718                            AppGlobals.getPackageManager().setPackageStoppedState(
10719                                    cpr.appInfo.packageName, false, userId);
10720                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10721                        } catch (RemoteException e) {
10722                        } catch (IllegalArgumentException e) {
10723                            Slog.w(TAG, "Failed trying to unstop package "
10724                                    + cpr.appInfo.packageName + ": " + e);
10725                        }
10726
10727                        // Use existing process if already started
10728                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10729                        ProcessRecord proc = getProcessRecordLocked(
10730                                cpi.processName, cpr.appInfo.uid, false);
10731                        if (proc != null && proc.thread != null && !proc.killed) {
10732                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10733                                    "Installing in existing process " + proc);
10734                            if (!proc.pubProviders.containsKey(cpi.name)) {
10735                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10736                                proc.pubProviders.put(cpi.name, cpr);
10737                                try {
10738                                    proc.thread.scheduleInstallProvider(cpi);
10739                                } catch (RemoteException e) {
10740                                }
10741                            }
10742                        } else {
10743                            checkTime(startTime, "getContentProviderImpl: before start process");
10744                            proc = startProcessLocked(cpi.processName,
10745                                    cpr.appInfo, false, 0, "content provider",
10746                                    new ComponentName(cpi.applicationInfo.packageName,
10747                                            cpi.name), false, false, false);
10748                            checkTime(startTime, "getContentProviderImpl: after start process");
10749                            if (proc == null) {
10750                                Slog.w(TAG, "Unable to launch app "
10751                                        + cpi.applicationInfo.packageName + "/"
10752                                        + cpi.applicationInfo.uid + " for provider "
10753                                        + name + ": process is bad");
10754                                return null;
10755                            }
10756                        }
10757                        cpr.launchingApp = proc;
10758                        mLaunchingProviders.add(cpr);
10759                    } finally {
10760                        Binder.restoreCallingIdentity(origId);
10761                    }
10762                }
10763
10764                checkTime(startTime, "getContentProviderImpl: updating data structures");
10765
10766                // Make sure the provider is published (the same provider class
10767                // may be published under multiple names).
10768                if (firstClass) {
10769                    mProviderMap.putProviderByClass(comp, cpr);
10770                }
10771
10772                mProviderMap.putProviderByName(name, cpr);
10773                conn = incProviderCountLocked(r, cpr, token, stable);
10774                if (conn != null) {
10775                    conn.waiting = true;
10776                }
10777            }
10778            checkTime(startTime, "getContentProviderImpl: done!");
10779        }
10780
10781        // Wait for the provider to be published...
10782        synchronized (cpr) {
10783            while (cpr.provider == null) {
10784                if (cpr.launchingApp == null) {
10785                    Slog.w(TAG, "Unable to launch app "
10786                            + cpi.applicationInfo.packageName + "/"
10787                            + cpi.applicationInfo.uid + " for provider "
10788                            + name + ": launching app became null");
10789                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10790                            UserHandle.getUserId(cpi.applicationInfo.uid),
10791                            cpi.applicationInfo.packageName,
10792                            cpi.applicationInfo.uid, name);
10793                    return null;
10794                }
10795                try {
10796                    if (DEBUG_MU) Slog.v(TAG_MU,
10797                            "Waiting to start provider " + cpr
10798                            + " launchingApp=" + cpr.launchingApp);
10799                    if (conn != null) {
10800                        conn.waiting = true;
10801                    }
10802                    cpr.wait();
10803                } catch (InterruptedException ex) {
10804                } finally {
10805                    if (conn != null) {
10806                        conn.waiting = false;
10807                    }
10808                }
10809            }
10810        }
10811        return cpr != null ? cpr.newHolder(conn) : null;
10812    }
10813
10814    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10815            ProcessRecord r, final int userId) {
10816        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10817                cpi.packageName, userId)) {
10818
10819            final boolean callerForeground = r == null || r.setSchedGroup
10820                    != ProcessList.SCHED_GROUP_BACKGROUND;
10821
10822            // Show a permission review UI only for starting from a foreground app
10823            if (!callerForeground) {
10824                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10825                        + cpi.packageName + " requires a permissions review");
10826                return false;
10827            }
10828
10829            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10830            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10831                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10832            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10833
10834            if (DEBUG_PERMISSIONS_REVIEW) {
10835                Slog.i(TAG, "u" + userId + " Launching permission review "
10836                        + "for package " + cpi.packageName);
10837            }
10838
10839            final UserHandle userHandle = new UserHandle(userId);
10840            mHandler.post(new Runnable() {
10841                @Override
10842                public void run() {
10843                    mContext.startActivityAsUser(intent, userHandle);
10844                }
10845            });
10846
10847            return false;
10848        }
10849
10850        return true;
10851    }
10852
10853    PackageManagerInternal getPackageManagerInternalLocked() {
10854        if (mPackageManagerInt == null) {
10855            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10856        }
10857        return mPackageManagerInt;
10858    }
10859
10860    @Override
10861    public final ContentProviderHolder getContentProvider(
10862            IApplicationThread caller, String name, int userId, boolean stable) {
10863        enforceNotIsolatedCaller("getContentProvider");
10864        if (caller == null) {
10865            String msg = "null IApplicationThread when getting content provider "
10866                    + name;
10867            Slog.w(TAG, msg);
10868            throw new SecurityException(msg);
10869        }
10870        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10871        // with cross-user grant.
10872        return getContentProviderImpl(caller, name, null, stable, userId);
10873    }
10874
10875    public ContentProviderHolder getContentProviderExternal(
10876            String name, int userId, IBinder token) {
10877        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10878            "Do not have permission in call getContentProviderExternal()");
10879        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10880                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10881        return getContentProviderExternalUnchecked(name, token, userId);
10882    }
10883
10884    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10885            IBinder token, int userId) {
10886        return getContentProviderImpl(null, name, token, true, userId);
10887    }
10888
10889    /**
10890     * Drop a content provider from a ProcessRecord's bookkeeping
10891     */
10892    public void removeContentProvider(IBinder connection, boolean stable) {
10893        enforceNotIsolatedCaller("removeContentProvider");
10894        long ident = Binder.clearCallingIdentity();
10895        try {
10896            synchronized (this) {
10897                ContentProviderConnection conn;
10898                try {
10899                    conn = (ContentProviderConnection)connection;
10900                } catch (ClassCastException e) {
10901                    String msg ="removeContentProvider: " + connection
10902                            + " not a ContentProviderConnection";
10903                    Slog.w(TAG, msg);
10904                    throw new IllegalArgumentException(msg);
10905                }
10906                if (conn == null) {
10907                    throw new NullPointerException("connection is null");
10908                }
10909                if (decProviderCountLocked(conn, null, null, stable)) {
10910                    updateOomAdjLocked();
10911                }
10912            }
10913        } finally {
10914            Binder.restoreCallingIdentity(ident);
10915        }
10916    }
10917
10918    public void removeContentProviderExternal(String name, IBinder token) {
10919        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10920            "Do not have permission in call removeContentProviderExternal()");
10921        int userId = UserHandle.getCallingUserId();
10922        long ident = Binder.clearCallingIdentity();
10923        try {
10924            removeContentProviderExternalUnchecked(name, token, userId);
10925        } finally {
10926            Binder.restoreCallingIdentity(ident);
10927        }
10928    }
10929
10930    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10931        synchronized (this) {
10932            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10933            if(cpr == null) {
10934                //remove from mProvidersByClass
10935                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10936                return;
10937            }
10938
10939            //update content provider record entry info
10940            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10941            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10942            if (localCpr.hasExternalProcessHandles()) {
10943                if (localCpr.removeExternalProcessHandleLocked(token)) {
10944                    updateOomAdjLocked();
10945                } else {
10946                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10947                            + " with no external reference for token: "
10948                            + token + ".");
10949                }
10950            } else {
10951                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10952                        + " with no external references.");
10953            }
10954        }
10955    }
10956
10957    public final void publishContentProviders(IApplicationThread caller,
10958            List<ContentProviderHolder> providers) {
10959        if (providers == null) {
10960            return;
10961        }
10962
10963        enforceNotIsolatedCaller("publishContentProviders");
10964        synchronized (this) {
10965            final ProcessRecord r = getRecordForAppLocked(caller);
10966            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10967            if (r == null) {
10968                throw new SecurityException(
10969                        "Unable to find app for caller " + caller
10970                      + " (pid=" + Binder.getCallingPid()
10971                      + ") when publishing content providers");
10972            }
10973
10974            final long origId = Binder.clearCallingIdentity();
10975
10976            final int N = providers.size();
10977            for (int i = 0; i < N; i++) {
10978                ContentProviderHolder src = providers.get(i);
10979                if (src == null || src.info == null || src.provider == null) {
10980                    continue;
10981                }
10982                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10983                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10984                if (dst != null) {
10985                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10986                    mProviderMap.putProviderByClass(comp, dst);
10987                    String names[] = dst.info.authority.split(";");
10988                    for (int j = 0; j < names.length; j++) {
10989                        mProviderMap.putProviderByName(names[j], dst);
10990                    }
10991
10992                    int launchingCount = mLaunchingProviders.size();
10993                    int j;
10994                    boolean wasInLaunchingProviders = false;
10995                    for (j = 0; j < launchingCount; j++) {
10996                        if (mLaunchingProviders.get(j) == dst) {
10997                            mLaunchingProviders.remove(j);
10998                            wasInLaunchingProviders = true;
10999                            j--;
11000                            launchingCount--;
11001                        }
11002                    }
11003                    if (wasInLaunchingProviders) {
11004                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11005                    }
11006                    synchronized (dst) {
11007                        dst.provider = src.provider;
11008                        dst.proc = r;
11009                        dst.notifyAll();
11010                    }
11011                    updateOomAdjLocked(r);
11012                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11013                            src.info.authority);
11014                }
11015            }
11016
11017            Binder.restoreCallingIdentity(origId);
11018        }
11019    }
11020
11021    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11022        ContentProviderConnection conn;
11023        try {
11024            conn = (ContentProviderConnection)connection;
11025        } catch (ClassCastException e) {
11026            String msg ="refContentProvider: " + connection
11027                    + " not a ContentProviderConnection";
11028            Slog.w(TAG, msg);
11029            throw new IllegalArgumentException(msg);
11030        }
11031        if (conn == null) {
11032            throw new NullPointerException("connection is null");
11033        }
11034
11035        synchronized (this) {
11036            if (stable > 0) {
11037                conn.numStableIncs += stable;
11038            }
11039            stable = conn.stableCount + stable;
11040            if (stable < 0) {
11041                throw new IllegalStateException("stableCount < 0: " + stable);
11042            }
11043
11044            if (unstable > 0) {
11045                conn.numUnstableIncs += unstable;
11046            }
11047            unstable = conn.unstableCount + unstable;
11048            if (unstable < 0) {
11049                throw new IllegalStateException("unstableCount < 0: " + unstable);
11050            }
11051
11052            if ((stable+unstable) <= 0) {
11053                throw new IllegalStateException("ref counts can't go to zero here: stable="
11054                        + stable + " unstable=" + unstable);
11055            }
11056            conn.stableCount = stable;
11057            conn.unstableCount = unstable;
11058            return !conn.dead;
11059        }
11060    }
11061
11062    public void unstableProviderDied(IBinder connection) {
11063        ContentProviderConnection conn;
11064        try {
11065            conn = (ContentProviderConnection)connection;
11066        } catch (ClassCastException e) {
11067            String msg ="refContentProvider: " + connection
11068                    + " not a ContentProviderConnection";
11069            Slog.w(TAG, msg);
11070            throw new IllegalArgumentException(msg);
11071        }
11072        if (conn == null) {
11073            throw new NullPointerException("connection is null");
11074        }
11075
11076        // Safely retrieve the content provider associated with the connection.
11077        IContentProvider provider;
11078        synchronized (this) {
11079            provider = conn.provider.provider;
11080        }
11081
11082        if (provider == null) {
11083            // Um, yeah, we're way ahead of you.
11084            return;
11085        }
11086
11087        // Make sure the caller is being honest with us.
11088        if (provider.asBinder().pingBinder()) {
11089            // Er, no, still looks good to us.
11090            synchronized (this) {
11091                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11092                        + " says " + conn + " died, but we don't agree");
11093                return;
11094            }
11095        }
11096
11097        // Well look at that!  It's dead!
11098        synchronized (this) {
11099            if (conn.provider.provider != provider) {
11100                // But something changed...  good enough.
11101                return;
11102            }
11103
11104            ProcessRecord proc = conn.provider.proc;
11105            if (proc == null || proc.thread == null) {
11106                // Seems like the process is already cleaned up.
11107                return;
11108            }
11109
11110            // As far as we're concerned, this is just like receiving a
11111            // death notification...  just a bit prematurely.
11112            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11113                    + ") early provider death");
11114            final long ident = Binder.clearCallingIdentity();
11115            try {
11116                appDiedLocked(proc);
11117            } finally {
11118                Binder.restoreCallingIdentity(ident);
11119            }
11120        }
11121    }
11122
11123    @Override
11124    public void appNotRespondingViaProvider(IBinder connection) {
11125        enforceCallingPermission(
11126                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11127
11128        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11129        if (conn == null) {
11130            Slog.w(TAG, "ContentProviderConnection is null");
11131            return;
11132        }
11133
11134        final ProcessRecord host = conn.provider.proc;
11135        if (host == null) {
11136            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11137            return;
11138        }
11139
11140        mHandler.post(new Runnable() {
11141            @Override
11142            public void run() {
11143                mAppErrors.appNotResponding(host, null, null, false,
11144                        "ContentProvider not responding");
11145            }
11146        });
11147    }
11148
11149    public final void installSystemProviders() {
11150        List<ProviderInfo> providers;
11151        synchronized (this) {
11152            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11153            providers = generateApplicationProvidersLocked(app);
11154            if (providers != null) {
11155                for (int i=providers.size()-1; i>=0; i--) {
11156                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11157                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11158                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11159                                + ": not system .apk");
11160                        providers.remove(i);
11161                    }
11162                }
11163            }
11164        }
11165        if (providers != null) {
11166            mSystemThread.installSystemProviders(providers);
11167        }
11168
11169        mCoreSettingsObserver = new CoreSettingsObserver(this);
11170        mFontScaleSettingObserver = new FontScaleSettingObserver();
11171
11172        //mUsageStatsService.monitorPackages();
11173    }
11174
11175    private void startPersistentApps(int matchFlags) {
11176        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11177
11178        synchronized (this) {
11179            try {
11180                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11181                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11182                for (ApplicationInfo app : apps) {
11183                    if (!"android".equals(app.packageName)) {
11184                        addAppLocked(app, false, null /* ABI override */);
11185                    }
11186                }
11187            } catch (RemoteException ex) {
11188            }
11189        }
11190    }
11191
11192    /**
11193     * When a user is unlocked, we need to install encryption-unaware providers
11194     * belonging to any running apps.
11195     */
11196    private void installEncryptionUnawareProviders(int userId) {
11197        // We're only interested in providers that are encryption unaware, and
11198        // we don't care about uninstalled apps, since there's no way they're
11199        // running at this point.
11200        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11201
11202        synchronized (this) {
11203            final int NP = mProcessNames.getMap().size();
11204            for (int ip = 0; ip < NP; ip++) {
11205                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11206                final int NA = apps.size();
11207                for (int ia = 0; ia < NA; ia++) {
11208                    final ProcessRecord app = apps.valueAt(ia);
11209                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11210
11211                    final int NG = app.pkgList.size();
11212                    for (int ig = 0; ig < NG; ig++) {
11213                        try {
11214                            final String pkgName = app.pkgList.keyAt(ig);
11215                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11216                                    .getPackageInfo(pkgName, matchFlags, userId);
11217                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11218                                for (ProviderInfo pi : pkgInfo.providers) {
11219                                    // TODO: keep in sync with generateApplicationProvidersLocked
11220                                    final boolean processMatch = Objects.equals(pi.processName,
11221                                            app.processName) || pi.multiprocess;
11222                                    final boolean userMatch = isSingleton(pi.processName,
11223                                            pi.applicationInfo, pi.name, pi.flags)
11224                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11225                                    if (processMatch && userMatch) {
11226                                        Log.v(TAG, "Installing " + pi);
11227                                        app.thread.scheduleInstallProvider(pi);
11228                                    } else {
11229                                        Log.v(TAG, "Skipping " + pi);
11230                                    }
11231                                }
11232                            }
11233                        } catch (RemoteException ignored) {
11234                        }
11235                    }
11236                }
11237            }
11238        }
11239    }
11240
11241    /**
11242     * Allows apps to retrieve the MIME type of a URI.
11243     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11244     * users, then it does not need permission to access the ContentProvider.
11245     * Either, it needs cross-user uri grants.
11246     *
11247     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11248     *
11249     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11250     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11251     */
11252    public String getProviderMimeType(Uri uri, int userId) {
11253        enforceNotIsolatedCaller("getProviderMimeType");
11254        final String name = uri.getAuthority();
11255        int callingUid = Binder.getCallingUid();
11256        int callingPid = Binder.getCallingPid();
11257        long ident = 0;
11258        boolean clearedIdentity = false;
11259        synchronized (this) {
11260            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11261        }
11262        if (canClearIdentity(callingPid, callingUid, userId)) {
11263            clearedIdentity = true;
11264            ident = Binder.clearCallingIdentity();
11265        }
11266        ContentProviderHolder holder = null;
11267        try {
11268            holder = getContentProviderExternalUnchecked(name, null, userId);
11269            if (holder != null) {
11270                return holder.provider.getType(uri);
11271            }
11272        } catch (RemoteException e) {
11273            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11274            return null;
11275        } catch (Exception e) {
11276            Log.w(TAG, "Exception while determining type of " + uri, e);
11277            return null;
11278        } finally {
11279            // We need to clear the identity to call removeContentProviderExternalUnchecked
11280            if (!clearedIdentity) {
11281                ident = Binder.clearCallingIdentity();
11282            }
11283            try {
11284                if (holder != null) {
11285                    removeContentProviderExternalUnchecked(name, null, userId);
11286                }
11287            } finally {
11288                Binder.restoreCallingIdentity(ident);
11289            }
11290        }
11291
11292        return null;
11293    }
11294
11295    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11296        if (UserHandle.getUserId(callingUid) == userId) {
11297            return true;
11298        }
11299        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11300                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11301                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11302                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11303                return true;
11304        }
11305        return false;
11306    }
11307
11308    // =========================================================
11309    // GLOBAL MANAGEMENT
11310    // =========================================================
11311
11312    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11313            boolean isolated, int isolatedUid) {
11314        String proc = customProcess != null ? customProcess : info.processName;
11315        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11316        final int userId = UserHandle.getUserId(info.uid);
11317        int uid = info.uid;
11318        if (isolated) {
11319            if (isolatedUid == 0) {
11320                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11321                while (true) {
11322                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11323                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11324                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11325                    }
11326                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11327                    mNextIsolatedProcessUid++;
11328                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11329                        // No process for this uid, use it.
11330                        break;
11331                    }
11332                    stepsLeft--;
11333                    if (stepsLeft <= 0) {
11334                        return null;
11335                    }
11336                }
11337            } else {
11338                // Special case for startIsolatedProcess (internal only), where
11339                // the uid of the isolated process is specified by the caller.
11340                uid = isolatedUid;
11341            }
11342
11343            // Register the isolated UID with this application so BatteryStats knows to
11344            // attribute resource usage to the application.
11345            //
11346            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11347            // about the process state of the isolated UID *before* it is registered with the
11348            // owning application.
11349            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11350        }
11351        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11352        if (!mBooted && !mBooting
11353                && userId == UserHandle.USER_SYSTEM
11354                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11355            r.persistent = true;
11356            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11357        }
11358        addProcessNameLocked(r);
11359        return r;
11360    }
11361
11362    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11363            String abiOverride) {
11364        ProcessRecord app;
11365        if (!isolated) {
11366            app = getProcessRecordLocked(info.processName, info.uid, true);
11367        } else {
11368            app = null;
11369        }
11370
11371        if (app == null) {
11372            app = newProcessRecordLocked(info, null, isolated, 0);
11373            updateLruProcessLocked(app, false, null);
11374            updateOomAdjLocked();
11375        }
11376
11377        // This package really, really can not be stopped.
11378        try {
11379            AppGlobals.getPackageManager().setPackageStoppedState(
11380                    info.packageName, false, UserHandle.getUserId(app.uid));
11381        } catch (RemoteException e) {
11382        } catch (IllegalArgumentException e) {
11383            Slog.w(TAG, "Failed trying to unstop package "
11384                    + info.packageName + ": " + e);
11385        }
11386
11387        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11388            app.persistent = true;
11389            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11390        }
11391        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11392            mPersistentStartingProcesses.add(app);
11393            startProcessLocked(app, "added application", app.processName, abiOverride,
11394                    null /* entryPoint */, null /* entryPointArgs */);
11395        }
11396
11397        return app;
11398    }
11399
11400    public void unhandledBack() {
11401        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11402                "unhandledBack()");
11403
11404        synchronized(this) {
11405            final long origId = Binder.clearCallingIdentity();
11406            try {
11407                getFocusedStack().unhandledBackLocked();
11408            } finally {
11409                Binder.restoreCallingIdentity(origId);
11410            }
11411        }
11412    }
11413
11414    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11415        enforceNotIsolatedCaller("openContentUri");
11416        final int userId = UserHandle.getCallingUserId();
11417        final Uri uri = Uri.parse(uriString);
11418        String name = uri.getAuthority();
11419        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11420        ParcelFileDescriptor pfd = null;
11421        if (cph != null) {
11422            // We record the binder invoker's uid in thread-local storage before
11423            // going to the content provider to open the file.  Later, in the code
11424            // that handles all permissions checks, we look for this uid and use
11425            // that rather than the Activity Manager's own uid.  The effect is that
11426            // we do the check against the caller's permissions even though it looks
11427            // to the content provider like the Activity Manager itself is making
11428            // the request.
11429            Binder token = new Binder();
11430            sCallerIdentity.set(new Identity(
11431                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11432            try {
11433                pfd = cph.provider.openFile(null, uri, "r", null, token);
11434            } catch (FileNotFoundException e) {
11435                // do nothing; pfd will be returned null
11436            } finally {
11437                // Ensure that whatever happens, we clean up the identity state
11438                sCallerIdentity.remove();
11439                // Ensure we're done with the provider.
11440                removeContentProviderExternalUnchecked(name, null, userId);
11441            }
11442        } else {
11443            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11444        }
11445        return pfd;
11446    }
11447
11448    // Actually is sleeping or shutting down or whatever else in the future
11449    // is an inactive state.
11450    boolean isSleepingOrShuttingDownLocked() {
11451        return isSleepingLocked() || mShuttingDown;
11452    }
11453
11454    boolean isShuttingDownLocked() {
11455        return mShuttingDown;
11456    }
11457
11458    boolean isSleepingLocked() {
11459        return mSleeping;
11460    }
11461
11462    void onWakefulnessChanged(int wakefulness) {
11463        synchronized(this) {
11464            mWakefulness = wakefulness;
11465            updateSleepIfNeededLocked();
11466        }
11467    }
11468
11469    void finishRunningVoiceLocked() {
11470        if (mRunningVoice != null) {
11471            mRunningVoice = null;
11472            mVoiceWakeLock.release();
11473            updateSleepIfNeededLocked();
11474        }
11475    }
11476
11477    void startTimeTrackingFocusedActivityLocked() {
11478        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11479        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11480            mCurAppTimeTracker.start(resumedActivity.packageName);
11481        }
11482    }
11483
11484    void updateSleepIfNeededLocked() {
11485        if (mSleeping && !shouldSleepLocked()) {
11486            mSleeping = false;
11487            startTimeTrackingFocusedActivityLocked();
11488            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11489            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11490            updateOomAdjLocked();
11491        } else if (!mSleeping && shouldSleepLocked()) {
11492            mSleeping = true;
11493            if (mCurAppTimeTracker != null) {
11494                mCurAppTimeTracker.stop();
11495            }
11496            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11497            mStackSupervisor.goingToSleepLocked();
11498            updateOomAdjLocked();
11499
11500            // Initialize the wake times of all processes.
11501            checkExcessivePowerUsageLocked(false);
11502            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11503            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11504            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11505        }
11506    }
11507
11508    private boolean shouldSleepLocked() {
11509        // Resume applications while running a voice interactor.
11510        if (mRunningVoice != null) {
11511            return false;
11512        }
11513
11514        // TODO: Transform the lock screen state into a sleep token instead.
11515        switch (mWakefulness) {
11516            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11517            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11518            case PowerManagerInternal.WAKEFULNESS_DOZING:
11519                // Pause applications whenever the lock screen is shown or any sleep
11520                // tokens have been acquired.
11521                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
11522            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11523            default:
11524                // If we're asleep then pause applications unconditionally.
11525                return true;
11526        }
11527    }
11528
11529    /** Pokes the task persister. */
11530    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11531        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11532    }
11533
11534    /** Notifies all listeners when the pinned stack animation ends. */
11535    @Override
11536    public void notifyPinnedStackAnimationEnded() {
11537        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11538    }
11539
11540    @Override
11541    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11542        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11543    }
11544
11545    @Override
11546    public boolean shutdown(int timeout) {
11547        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11548                != PackageManager.PERMISSION_GRANTED) {
11549            throw new SecurityException("Requires permission "
11550                    + android.Manifest.permission.SHUTDOWN);
11551        }
11552
11553        boolean timedout = false;
11554
11555        synchronized(this) {
11556            mShuttingDown = true;
11557            updateEventDispatchingLocked();
11558            timedout = mStackSupervisor.shutdownLocked(timeout);
11559        }
11560
11561        mAppOpsService.shutdown();
11562        if (mUsageStatsService != null) {
11563            mUsageStatsService.prepareShutdown();
11564        }
11565        mBatteryStatsService.shutdown();
11566        synchronized (this) {
11567            mProcessStats.shutdownLocked();
11568            notifyTaskPersisterLocked(null, true);
11569        }
11570
11571        return timedout;
11572    }
11573
11574    public final void activitySlept(IBinder token) {
11575        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11576
11577        final long origId = Binder.clearCallingIdentity();
11578
11579        synchronized (this) {
11580            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11581            if (r != null) {
11582                mStackSupervisor.activitySleptLocked(r);
11583            }
11584        }
11585
11586        Binder.restoreCallingIdentity(origId);
11587    }
11588
11589    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11590        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11591        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11592        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11593            boolean wasRunningVoice = mRunningVoice != null;
11594            mRunningVoice = session;
11595            if (!wasRunningVoice) {
11596                mVoiceWakeLock.acquire();
11597                updateSleepIfNeededLocked();
11598            }
11599        }
11600    }
11601
11602    private void updateEventDispatchingLocked() {
11603        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11604    }
11605
11606    @Override
11607    public void setLockScreenShown(boolean showing) {
11608        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11609                != PackageManager.PERMISSION_GRANTED) {
11610            throw new SecurityException("Requires permission "
11611                    + android.Manifest.permission.DEVICE_POWER);
11612        }
11613
11614        synchronized(this) {
11615            long ident = Binder.clearCallingIdentity();
11616            try {
11617                mKeyguardController.setKeyguardShown(showing);
11618            } finally {
11619                Binder.restoreCallingIdentity(ident);
11620            }
11621        }
11622    }
11623
11624    @Override
11625    public void notifyLockedProfile(@UserIdInt int userId) {
11626        try {
11627            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11628                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11629            }
11630        } catch (RemoteException ex) {
11631            throw new SecurityException("Fail to check is caller a privileged app", ex);
11632        }
11633
11634        synchronized (this) {
11635            if (mStackSupervisor.isUserLockedProfile(userId)) {
11636                final long ident = Binder.clearCallingIdentity();
11637                try {
11638                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11639                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11640                        // If there is no device lock, we will show the profile's credential page.
11641                        mActivityStarter.showConfirmDeviceCredential(userId);
11642                    } else {
11643                        // Showing launcher to avoid user entering credential twice.
11644                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11645                    }
11646                } finally {
11647                    Binder.restoreCallingIdentity(ident);
11648                }
11649            }
11650        }
11651    }
11652
11653    @Override
11654    public void startConfirmDeviceCredentialIntent(Intent intent) {
11655        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11656        synchronized (this) {
11657            final long ident = Binder.clearCallingIdentity();
11658            try {
11659                mActivityStarter.startConfirmCredentialIntent(intent);
11660            } finally {
11661                Binder.restoreCallingIdentity(ident);
11662            }
11663        }
11664    }
11665
11666    @Override
11667    public void stopAppSwitches() {
11668        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11669                != PackageManager.PERMISSION_GRANTED) {
11670            throw new SecurityException("viewquires permission "
11671                    + android.Manifest.permission.STOP_APP_SWITCHES);
11672        }
11673
11674        synchronized(this) {
11675            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11676                    + APP_SWITCH_DELAY_TIME;
11677            mDidAppSwitch = false;
11678            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11679            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11680            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11681        }
11682    }
11683
11684    public void resumeAppSwitches() {
11685        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11686                != PackageManager.PERMISSION_GRANTED) {
11687            throw new SecurityException("Requires permission "
11688                    + android.Manifest.permission.STOP_APP_SWITCHES);
11689        }
11690
11691        synchronized(this) {
11692            // Note that we don't execute any pending app switches... we will
11693            // let those wait until either the timeout, or the next start
11694            // activity request.
11695            mAppSwitchesAllowedTime = 0;
11696        }
11697    }
11698
11699    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11700            int callingPid, int callingUid, String name) {
11701        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11702            return true;
11703        }
11704
11705        int perm = checkComponentPermission(
11706                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11707                sourceUid, -1, true);
11708        if (perm == PackageManager.PERMISSION_GRANTED) {
11709            return true;
11710        }
11711
11712        // If the actual IPC caller is different from the logical source, then
11713        // also see if they are allowed to control app switches.
11714        if (callingUid != -1 && callingUid != sourceUid) {
11715            perm = checkComponentPermission(
11716                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11717                    callingUid, -1, true);
11718            if (perm == PackageManager.PERMISSION_GRANTED) {
11719                return true;
11720            }
11721        }
11722
11723        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11724        return false;
11725    }
11726
11727    public void setDebugApp(String packageName, boolean waitForDebugger,
11728            boolean persistent) {
11729        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11730                "setDebugApp()");
11731
11732        long ident = Binder.clearCallingIdentity();
11733        try {
11734            // Note that this is not really thread safe if there are multiple
11735            // callers into it at the same time, but that's not a situation we
11736            // care about.
11737            if (persistent) {
11738                final ContentResolver resolver = mContext.getContentResolver();
11739                Settings.Global.putString(
11740                    resolver, Settings.Global.DEBUG_APP,
11741                    packageName);
11742                Settings.Global.putInt(
11743                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11744                    waitForDebugger ? 1 : 0);
11745            }
11746
11747            synchronized (this) {
11748                if (!persistent) {
11749                    mOrigDebugApp = mDebugApp;
11750                    mOrigWaitForDebugger = mWaitForDebugger;
11751                }
11752                mDebugApp = packageName;
11753                mWaitForDebugger = waitForDebugger;
11754                mDebugTransient = !persistent;
11755                if (packageName != null) {
11756                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11757                            false, UserHandle.USER_ALL, "set debug app");
11758                }
11759            }
11760        } finally {
11761            Binder.restoreCallingIdentity(ident);
11762        }
11763    }
11764
11765    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11766        synchronized (this) {
11767            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11768            if (!isDebuggable) {
11769                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11770                    throw new SecurityException("Process not debuggable: " + app.packageName);
11771                }
11772            }
11773
11774            mTrackAllocationApp = processName;
11775        }
11776    }
11777
11778    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11779        synchronized (this) {
11780            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11781            if (!isDebuggable) {
11782                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11783                    throw new SecurityException("Process not debuggable: " + app.packageName);
11784                }
11785            }
11786            mProfileApp = processName;
11787            mProfileFile = profilerInfo.profileFile;
11788            if (mProfileFd != null) {
11789                try {
11790                    mProfileFd.close();
11791                } catch (IOException e) {
11792                }
11793                mProfileFd = null;
11794            }
11795            mProfileFd = profilerInfo.profileFd;
11796            mSamplingInterval = profilerInfo.samplingInterval;
11797            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11798            mProfileType = 0;
11799        }
11800    }
11801
11802    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11803        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11804        if (!isDebuggable) {
11805            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11806                throw new SecurityException("Process not debuggable: " + app.packageName);
11807            }
11808        }
11809        mNativeDebuggingApp = processName;
11810    }
11811
11812    @Override
11813    public void setAlwaysFinish(boolean enabled) {
11814        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11815                "setAlwaysFinish()");
11816
11817        long ident = Binder.clearCallingIdentity();
11818        try {
11819            Settings.Global.putInt(
11820                    mContext.getContentResolver(),
11821                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11822
11823            synchronized (this) {
11824                mAlwaysFinishActivities = enabled;
11825            }
11826        } finally {
11827            Binder.restoreCallingIdentity(ident);
11828        }
11829    }
11830
11831    @Override
11832    public void setLenientBackgroundCheck(boolean enabled) {
11833        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11834                "setLenientBackgroundCheck()");
11835
11836        long ident = Binder.clearCallingIdentity();
11837        try {
11838            Settings.Global.putInt(
11839                    mContext.getContentResolver(),
11840                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11841
11842            synchronized (this) {
11843                mLenientBackgroundCheck = enabled;
11844            }
11845        } finally {
11846            Binder.restoreCallingIdentity(ident);
11847        }
11848    }
11849
11850    @Override
11851    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11852        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11853                "setActivityController()");
11854        synchronized (this) {
11855            mController = controller;
11856            mControllerIsAMonkey = imAMonkey;
11857            Watchdog.getInstance().setActivityController(controller);
11858        }
11859    }
11860
11861    @Override
11862    public void setUserIsMonkey(boolean userIsMonkey) {
11863        synchronized (this) {
11864            synchronized (mPidsSelfLocked) {
11865                final int callingPid = Binder.getCallingPid();
11866                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11867                if (precessRecord == null) {
11868                    throw new SecurityException("Unknown process: " + callingPid);
11869                }
11870                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11871                    throw new SecurityException("Only an instrumentation process "
11872                            + "with a UiAutomation can call setUserIsMonkey");
11873                }
11874            }
11875            mUserIsMonkey = userIsMonkey;
11876        }
11877    }
11878
11879    @Override
11880    public boolean isUserAMonkey() {
11881        synchronized (this) {
11882            // If there is a controller also implies the user is a monkey.
11883            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11884        }
11885    }
11886
11887    public void requestBugReport(int bugreportType) {
11888        String extraOptions = null;
11889        switch (bugreportType) {
11890            case ActivityManager.BUGREPORT_OPTION_FULL:
11891                // Default options.
11892                break;
11893            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11894                extraOptions = "bugreportplus";
11895                break;
11896            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11897                extraOptions = "bugreportremote";
11898                break;
11899            case ActivityManager.BUGREPORT_OPTION_WEAR:
11900                extraOptions = "bugreportwear";
11901                break;
11902            default:
11903                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11904                        + bugreportType);
11905        }
11906        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11907        if (extraOptions != null) {
11908            SystemProperties.set("dumpstate.options", extraOptions);
11909        }
11910        SystemProperties.set("ctl.start", "bugreport");
11911    }
11912
11913    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11914        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11915    }
11916
11917    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11918        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11919            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11920        }
11921        return KEY_DISPATCHING_TIMEOUT;
11922    }
11923
11924    @Override
11925    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11926        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11927                != PackageManager.PERMISSION_GRANTED) {
11928            throw new SecurityException("Requires permission "
11929                    + android.Manifest.permission.FILTER_EVENTS);
11930        }
11931        ProcessRecord proc;
11932        long timeout;
11933        synchronized (this) {
11934            synchronized (mPidsSelfLocked) {
11935                proc = mPidsSelfLocked.get(pid);
11936            }
11937            timeout = getInputDispatchingTimeoutLocked(proc);
11938        }
11939
11940        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11941            return -1;
11942        }
11943
11944        return timeout;
11945    }
11946
11947    /**
11948     * Handle input dispatching timeouts.
11949     * Returns whether input dispatching should be aborted or not.
11950     */
11951    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11952            final ActivityRecord activity, final ActivityRecord parent,
11953            final boolean aboveSystem, String reason) {
11954        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11955                != PackageManager.PERMISSION_GRANTED) {
11956            throw new SecurityException("Requires permission "
11957                    + android.Manifest.permission.FILTER_EVENTS);
11958        }
11959
11960        final String annotation;
11961        if (reason == null) {
11962            annotation = "Input dispatching timed out";
11963        } else {
11964            annotation = "Input dispatching timed out (" + reason + ")";
11965        }
11966
11967        if (proc != null) {
11968            synchronized (this) {
11969                if (proc.debugging) {
11970                    return false;
11971                }
11972
11973                if (mDidDexOpt) {
11974                    // Give more time since we were dexopting.
11975                    mDidDexOpt = false;
11976                    return false;
11977                }
11978
11979                if (proc.instrumentationClass != null) {
11980                    Bundle info = new Bundle();
11981                    info.putString("shortMsg", "keyDispatchingTimedOut");
11982                    info.putString("longMsg", annotation);
11983                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11984                    return true;
11985                }
11986            }
11987            mHandler.post(new Runnable() {
11988                @Override
11989                public void run() {
11990                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11991                }
11992            });
11993        }
11994
11995        return true;
11996    }
11997
11998    @Override
11999    public Bundle getAssistContextExtras(int requestType) {
12000        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12001                null, null, true /* focused */, true /* newSessionId */,
12002                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12003        if (pae == null) {
12004            return null;
12005        }
12006        synchronized (pae) {
12007            while (!pae.haveResult) {
12008                try {
12009                    pae.wait();
12010                } catch (InterruptedException e) {
12011                }
12012            }
12013        }
12014        synchronized (this) {
12015            buildAssistBundleLocked(pae, pae.result);
12016            mPendingAssistExtras.remove(pae);
12017            mUiHandler.removeCallbacks(pae);
12018        }
12019        return pae.extras;
12020    }
12021
12022    @Override
12023    public boolean isAssistDataAllowedOnCurrentActivity() {
12024        int userId;
12025        synchronized (this) {
12026            userId = mUserController.getCurrentUserIdLocked();
12027            ActivityRecord activity = getFocusedStack().topActivity();
12028            if (activity == null) {
12029                return false;
12030            }
12031            userId = activity.userId;
12032        }
12033        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12034                Context.DEVICE_POLICY_SERVICE);
12035        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12036    }
12037
12038    @Override
12039    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12040        long ident = Binder.clearCallingIdentity();
12041        try {
12042            synchronized (this) {
12043                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12044                ActivityRecord top = getFocusedStack().topActivity();
12045                if (top != caller) {
12046                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12047                            + " is not current top " + top);
12048                    return false;
12049                }
12050                if (!top.nowVisible) {
12051                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12052                            + " is not visible");
12053                    return false;
12054                }
12055            }
12056            AssistUtils utils = new AssistUtils(mContext);
12057            return utils.showSessionForActiveService(args,
12058                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12059        } finally {
12060            Binder.restoreCallingIdentity(ident);
12061        }
12062    }
12063
12064    @Override
12065    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12066            Bundle receiverExtras,
12067            IBinder activityToken, boolean focused, boolean newSessionId) {
12068        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12069                activityToken, focused, newSessionId,
12070                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12071                != null;
12072    }
12073
12074    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12075            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12076            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12077        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12078                "enqueueAssistContext()");
12079        synchronized (this) {
12080            ActivityRecord activity = getFocusedStack().topActivity();
12081            if (activity == null) {
12082                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12083                return null;
12084            }
12085            if (activity.app == null || activity.app.thread == null) {
12086                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12087                return null;
12088            }
12089            if (focused) {
12090                if (activityToken != null) {
12091                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12092                    if (activity != caller) {
12093                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12094                                + " is not current top " + activity);
12095                        return null;
12096                    }
12097                }
12098            } else {
12099                activity = ActivityRecord.forTokenLocked(activityToken);
12100                if (activity == null) {
12101                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12102                            + " couldn't be found");
12103                    return null;
12104                }
12105            }
12106
12107            PendingAssistExtras pae;
12108            Bundle extras = new Bundle();
12109            if (args != null) {
12110                extras.putAll(args);
12111            }
12112            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12113            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12114            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12115                    userHandle);
12116            // Increment the sessionId if necessary
12117            if (newSessionId) {
12118                mViSessionId++;
12119            }
12120            try {
12121                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12122                        requestType, mViSessionId);
12123                mPendingAssistExtras.add(pae);
12124                mUiHandler.postDelayed(pae, timeout);
12125            } catch (RemoteException e) {
12126                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12127                return null;
12128            }
12129            return pae;
12130        }
12131    }
12132
12133    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12134        IResultReceiver receiver;
12135        synchronized (this) {
12136            mPendingAssistExtras.remove(pae);
12137            receiver = pae.receiver;
12138        }
12139        if (receiver != null) {
12140            // Caller wants result sent back to them.
12141            Bundle sendBundle = new Bundle();
12142            // At least return the receiver extras
12143            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12144                    pae.receiverExtras);
12145            try {
12146                pae.receiver.send(0, sendBundle);
12147            } catch (RemoteException e) {
12148            }
12149        }
12150    }
12151
12152    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12153        if (result != null) {
12154            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12155        }
12156        if (pae.hint != null) {
12157            pae.extras.putBoolean(pae.hint, true);
12158        }
12159    }
12160
12161    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12162            AssistContent content, Uri referrer) {
12163        PendingAssistExtras pae = (PendingAssistExtras)token;
12164        synchronized (pae) {
12165            pae.result = extras;
12166            pae.structure = structure;
12167            pae.content = content;
12168            if (referrer != null) {
12169                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12170            }
12171            pae.haveResult = true;
12172            pae.notifyAll();
12173            if (pae.intent == null && pae.receiver == null) {
12174                // Caller is just waiting for the result.
12175                return;
12176            }
12177        }
12178
12179        // We are now ready to launch the assist activity.
12180        IResultReceiver sendReceiver = null;
12181        Bundle sendBundle = null;
12182        synchronized (this) {
12183            buildAssistBundleLocked(pae, extras);
12184            boolean exists = mPendingAssistExtras.remove(pae);
12185            mUiHandler.removeCallbacks(pae);
12186            if (!exists) {
12187                // Timed out.
12188                return;
12189            }
12190            if ((sendReceiver=pae.receiver) != null) {
12191                // Caller wants result sent back to them.
12192                sendBundle = new Bundle();
12193                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12194                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12195                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12196                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12197                        pae.receiverExtras);
12198            }
12199        }
12200        if (sendReceiver != null) {
12201            try {
12202                sendReceiver.send(0, sendBundle);
12203            } catch (RemoteException e) {
12204            }
12205            return;
12206        }
12207
12208        long ident = Binder.clearCallingIdentity();
12209        try {
12210            pae.intent.replaceExtras(pae.extras);
12211            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12212                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12213                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12214            closeSystemDialogs("assist");
12215            try {
12216                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12217            } catch (ActivityNotFoundException e) {
12218                Slog.w(TAG, "No activity to handle assist action.", e);
12219            }
12220        } finally {
12221            Binder.restoreCallingIdentity(ident);
12222        }
12223    }
12224
12225    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12226            Bundle args) {
12227        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12228                true /* focused */, true /* newSessionId */,
12229                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12230    }
12231
12232    public void registerProcessObserver(IProcessObserver observer) {
12233        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12234                "registerProcessObserver()");
12235        synchronized (this) {
12236            mProcessObservers.register(observer);
12237        }
12238    }
12239
12240    @Override
12241    public void unregisterProcessObserver(IProcessObserver observer) {
12242        synchronized (this) {
12243            mProcessObservers.unregister(observer);
12244        }
12245    }
12246
12247    @Override
12248    public void registerUidObserver(IUidObserver observer, int which, String callingPackage) {
12249        if (!hasUsageStatsPermission(callingPackage)) {
12250            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12251                    "registerUidObserver");
12252        }
12253        synchronized (this) {
12254            mUidObservers.register(observer, which);
12255        }
12256    }
12257
12258    @Override
12259    public void unregisterUidObserver(IUidObserver observer) {
12260        synchronized (this) {
12261            mUidObservers.unregister(observer);
12262        }
12263    }
12264
12265    @Override
12266    public boolean convertFromTranslucent(IBinder token) {
12267        final long origId = Binder.clearCallingIdentity();
12268        try {
12269            synchronized (this) {
12270                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12271                if (r == null) {
12272                    return false;
12273                }
12274                final boolean translucentChanged = r.changeWindowTranslucency(true);
12275                if (translucentChanged) {
12276                    r.getStack().releaseBackgroundResources(r);
12277                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12278                }
12279                mWindowManager.setAppFullscreen(token, true);
12280                return translucentChanged;
12281            }
12282        } finally {
12283            Binder.restoreCallingIdentity(origId);
12284        }
12285    }
12286
12287    @Override
12288    public boolean convertToTranslucent(IBinder token, Bundle options) {
12289        final long origId = Binder.clearCallingIdentity();
12290        try {
12291            synchronized (this) {
12292                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12293                if (r == null) {
12294                    return false;
12295                }
12296                int index = r.task.mActivities.lastIndexOf(r);
12297                if (index > 0) {
12298                    ActivityRecord under = r.task.mActivities.get(index - 1);
12299                    under.returningOptions = ActivityOptions.fromBundle(options);
12300                }
12301                final boolean translucentChanged = r.changeWindowTranslucency(false);
12302                if (translucentChanged) {
12303                    r.getStack().convertActivityToTranslucent(r);
12304                }
12305                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12306                mWindowManager.setAppFullscreen(token, false);
12307                return translucentChanged;
12308            }
12309        } finally {
12310            Binder.restoreCallingIdentity(origId);
12311        }
12312    }
12313
12314    @Override
12315    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12316        final long origId = Binder.clearCallingIdentity();
12317        try {
12318            synchronized (this) {
12319                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12320                if (r != null) {
12321                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12322                }
12323            }
12324            return false;
12325        } finally {
12326            Binder.restoreCallingIdentity(origId);
12327        }
12328    }
12329
12330    @Override
12331    public boolean isBackgroundVisibleBehind(IBinder token) {
12332        final long origId = Binder.clearCallingIdentity();
12333        try {
12334            synchronized (this) {
12335                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12336                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12337                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12338                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12339                return visible;
12340            }
12341        } finally {
12342            Binder.restoreCallingIdentity(origId);
12343        }
12344    }
12345
12346    @Override
12347    public Bundle getActivityOptions(IBinder token) {
12348        final long origId = Binder.clearCallingIdentity();
12349        try {
12350            synchronized (this) {
12351                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12352                if (r != null) {
12353                    final ActivityOptions activityOptions = r.pendingOptions;
12354                    r.pendingOptions = null;
12355                    return activityOptions == null ? null : activityOptions.toBundle();
12356                }
12357                return null;
12358            }
12359        } finally {
12360            Binder.restoreCallingIdentity(origId);
12361        }
12362    }
12363
12364    @Override
12365    public void setImmersive(IBinder token, boolean immersive) {
12366        synchronized(this) {
12367            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12368            if (r == null) {
12369                throw new IllegalArgumentException();
12370            }
12371            r.immersive = immersive;
12372
12373            // update associated state if we're frontmost
12374            if (r == mStackSupervisor.getResumedActivityLocked()) {
12375                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12376                applyUpdateLockStateLocked(r);
12377            }
12378        }
12379    }
12380
12381    @Override
12382    public boolean isImmersive(IBinder token) {
12383        synchronized (this) {
12384            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12385            if (r == null) {
12386                throw new IllegalArgumentException();
12387            }
12388            return r.immersive;
12389        }
12390    }
12391
12392    public void setVrThread(int tid) {
12393        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12394            throw new UnsupportedOperationException("VR mode not supported on this device!");
12395        }
12396
12397        synchronized (this) {
12398            ProcessRecord proc;
12399            synchronized (mPidsSelfLocked) {
12400                final int pid = Binder.getCallingPid();
12401                proc = mPidsSelfLocked.get(pid);
12402
12403                if (proc != null && mInVrMode && tid >= 0) {
12404                    // ensure the tid belongs to the process
12405                    if (!Process.isThreadInProcess(pid, tid)) {
12406                        throw new IllegalArgumentException("VR thread does not belong to process");
12407                    }
12408
12409                    // reset existing VR thread to CFS if this thread still exists and belongs to
12410                    // the calling process
12411                    if (proc.vrThreadTid != 0
12412                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12413                        try {
12414                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12415                        } catch (IllegalArgumentException e) {
12416                            // Ignore this.  Only occurs in race condition where previous VR thread
12417                            // was destroyed during this method call.
12418                        }
12419                    }
12420
12421                    proc.vrThreadTid = tid;
12422
12423                    // promote to FIFO now if the tid is non-zero
12424                    try {
12425                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12426                            proc.vrThreadTid > 0) {
12427                            Process.setThreadScheduler(proc.vrThreadTid,
12428                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12429                        }
12430                    } catch (IllegalArgumentException e) {
12431                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12432                               + " not exist:\n" + e);
12433                    }
12434                }
12435            }
12436        }
12437    }
12438
12439    @Override
12440    public void setRenderThread(int tid) {
12441        synchronized (this) {
12442            ProcessRecord proc;
12443            synchronized (mPidsSelfLocked) {
12444                int pid = Binder.getCallingPid();
12445                proc = mPidsSelfLocked.get(pid);
12446                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12447                    // ensure the tid belongs to the process
12448                    if (!Process.isThreadInProcess(pid, tid)) {
12449                        throw new IllegalArgumentException(
12450                            "Render thread does not belong to process");
12451                    }
12452                    proc.renderThreadTid = tid;
12453                    if (DEBUG_OOM_ADJ) {
12454                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12455                    }
12456                    // promote to FIFO now
12457                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12458                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12459                        if (mUseFifoUiScheduling) {
12460                            Process.setThreadScheduler(proc.renderThreadTid,
12461                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12462                        } else {
12463                            Process.setThreadPriority(proc.renderThreadTid, -10);
12464                        }
12465                    }
12466                } else {
12467                    if (DEBUG_OOM_ADJ) {
12468                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12469                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12470                               mUseFifoUiScheduling);
12471                    }
12472                }
12473            }
12474        }
12475    }
12476
12477    @Override
12478    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12479        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12480            throw new UnsupportedOperationException("VR mode not supported on this device!");
12481        }
12482
12483        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12484
12485        ActivityRecord r;
12486        synchronized (this) {
12487            r = ActivityRecord.isInStackLocked(token);
12488        }
12489
12490        if (r == null) {
12491            throw new IllegalArgumentException();
12492        }
12493
12494        int err;
12495        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12496                VrManagerInternal.NO_ERROR) {
12497            return err;
12498        }
12499
12500        synchronized(this) {
12501            r.requestedVrComponent = (enabled) ? packageName : null;
12502
12503            // Update associated state if this activity is currently focused
12504            if (r == mStackSupervisor.getResumedActivityLocked()) {
12505                applyUpdateVrModeLocked(r);
12506            }
12507            return 0;
12508        }
12509    }
12510
12511    @Override
12512    public boolean isVrModePackageEnabled(ComponentName packageName) {
12513        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12514            throw new UnsupportedOperationException("VR mode not supported on this device!");
12515        }
12516
12517        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12518
12519        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12520                VrManagerInternal.NO_ERROR;
12521    }
12522
12523    public boolean isTopActivityImmersive() {
12524        enforceNotIsolatedCaller("startActivity");
12525        synchronized (this) {
12526            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12527            return (r != null) ? r.immersive : false;
12528        }
12529    }
12530
12531    @Override
12532    public boolean isTopOfTask(IBinder token) {
12533        synchronized (this) {
12534            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12535            if (r == null) {
12536                throw new IllegalArgumentException();
12537            }
12538            return r.task.getTopActivity() == r;
12539        }
12540    }
12541
12542    @Override
12543    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12544        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12545            String msg = "Permission Denial: setHasTopUi() from pid="
12546                    + Binder.getCallingPid()
12547                    + ", uid=" + Binder.getCallingUid()
12548                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12549            Slog.w(TAG, msg);
12550            throw new SecurityException(msg);
12551        }
12552        final int pid = Binder.getCallingPid();
12553        final long origId = Binder.clearCallingIdentity();
12554        try {
12555            synchronized (this) {
12556                boolean changed = false;
12557                ProcessRecord pr;
12558                synchronized (mPidsSelfLocked) {
12559                    pr = mPidsSelfLocked.get(pid);
12560                    if (pr == null) {
12561                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12562                        return;
12563                    }
12564                    if (pr.hasTopUi != hasTopUi) {
12565                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12566                        pr.hasTopUi = hasTopUi;
12567                        changed = true;
12568                    }
12569                }
12570                if (changed) {
12571                    updateOomAdjLocked(pr);
12572                }
12573            }
12574        } finally {
12575            Binder.restoreCallingIdentity(origId);
12576        }
12577    }
12578
12579    public final void enterSafeMode() {
12580        synchronized(this) {
12581            // It only makes sense to do this before the system is ready
12582            // and started launching other packages.
12583            if (!mSystemReady) {
12584                try {
12585                    AppGlobals.getPackageManager().enterSafeMode();
12586                } catch (RemoteException e) {
12587                }
12588            }
12589
12590            mSafeMode = true;
12591        }
12592    }
12593
12594    public final void showSafeModeOverlay() {
12595        View v = LayoutInflater.from(mContext).inflate(
12596                com.android.internal.R.layout.safe_mode, null);
12597        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12598        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12599        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12600        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12601        lp.gravity = Gravity.BOTTOM | Gravity.START;
12602        lp.format = v.getBackground().getOpacity();
12603        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12604                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12605        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12606        ((WindowManager)mContext.getSystemService(
12607                Context.WINDOW_SERVICE)).addView(v, lp);
12608    }
12609
12610    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12611        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12612            return;
12613        }
12614        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12615        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12616        synchronized (stats) {
12617            if (mBatteryStatsService.isOnBattery()) {
12618                mBatteryStatsService.enforceCallingPermission();
12619                int MY_UID = Binder.getCallingUid();
12620                final int uid;
12621                if (sender == null) {
12622                    uid = sourceUid;
12623                } else {
12624                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12625                }
12626                BatteryStatsImpl.Uid.Pkg pkg =
12627                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12628                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12629                pkg.noteWakeupAlarmLocked(tag);
12630            }
12631        }
12632    }
12633
12634    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12635        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12636            return;
12637        }
12638        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12639        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12640        synchronized (stats) {
12641            mBatteryStatsService.enforceCallingPermission();
12642            int MY_UID = Binder.getCallingUid();
12643            final int uid;
12644            if (sender == null) {
12645                uid = sourceUid;
12646            } else {
12647                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12648            }
12649            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12650        }
12651    }
12652
12653    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12654        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12655            return;
12656        }
12657        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12658        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12659        synchronized (stats) {
12660            mBatteryStatsService.enforceCallingPermission();
12661            int MY_UID = Binder.getCallingUid();
12662            final int uid;
12663            if (sender == null) {
12664                uid = sourceUid;
12665            } else {
12666                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12667            }
12668            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12669        }
12670    }
12671
12672    public boolean killPids(int[] pids, String pReason, boolean secure) {
12673        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12674            throw new SecurityException("killPids only available to the system");
12675        }
12676        String reason = (pReason == null) ? "Unknown" : pReason;
12677        // XXX Note: don't acquire main activity lock here, because the window
12678        // manager calls in with its locks held.
12679
12680        boolean killed = false;
12681        synchronized (mPidsSelfLocked) {
12682            int worstType = 0;
12683            for (int i=0; i<pids.length; i++) {
12684                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12685                if (proc != null) {
12686                    int type = proc.setAdj;
12687                    if (type > worstType) {
12688                        worstType = type;
12689                    }
12690                }
12691            }
12692
12693            // If the worst oom_adj is somewhere in the cached proc LRU range,
12694            // then constrain it so we will kill all cached procs.
12695            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12696                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12697                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12698            }
12699
12700            // If this is not a secure call, don't let it kill processes that
12701            // are important.
12702            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12703                worstType = ProcessList.SERVICE_ADJ;
12704            }
12705
12706            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12707            for (int i=0; i<pids.length; i++) {
12708                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12709                if (proc == null) {
12710                    continue;
12711                }
12712                int adj = proc.setAdj;
12713                if (adj >= worstType && !proc.killedByAm) {
12714                    proc.kill(reason, true);
12715                    killed = true;
12716                }
12717            }
12718        }
12719        return killed;
12720    }
12721
12722    @Override
12723    public void killUid(int appId, int userId, String reason) {
12724        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12725        synchronized (this) {
12726            final long identity = Binder.clearCallingIdentity();
12727            try {
12728                killPackageProcessesLocked(null, appId, userId,
12729                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12730                        reason != null ? reason : "kill uid");
12731            } finally {
12732                Binder.restoreCallingIdentity(identity);
12733            }
12734        }
12735    }
12736
12737    @Override
12738    public boolean killProcessesBelowForeground(String reason) {
12739        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12740            throw new SecurityException("killProcessesBelowForeground() only available to system");
12741        }
12742
12743        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12744    }
12745
12746    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12747        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12748            throw new SecurityException("killProcessesBelowAdj() only available to system");
12749        }
12750
12751        boolean killed = false;
12752        synchronized (mPidsSelfLocked) {
12753            final int size = mPidsSelfLocked.size();
12754            for (int i = 0; i < size; i++) {
12755                final int pid = mPidsSelfLocked.keyAt(i);
12756                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12757                if (proc == null) continue;
12758
12759                final int adj = proc.setAdj;
12760                if (adj > belowAdj && !proc.killedByAm) {
12761                    proc.kill(reason, true);
12762                    killed = true;
12763                }
12764            }
12765        }
12766        return killed;
12767    }
12768
12769    @Override
12770    public void hang(final IBinder who, boolean allowRestart) {
12771        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12772                != PackageManager.PERMISSION_GRANTED) {
12773            throw new SecurityException("Requires permission "
12774                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12775        }
12776
12777        final IBinder.DeathRecipient death = new DeathRecipient() {
12778            @Override
12779            public void binderDied() {
12780                synchronized (this) {
12781                    notifyAll();
12782                }
12783            }
12784        };
12785
12786        try {
12787            who.linkToDeath(death, 0);
12788        } catch (RemoteException e) {
12789            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12790            return;
12791        }
12792
12793        synchronized (this) {
12794            Watchdog.getInstance().setAllowRestart(allowRestart);
12795            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12796            synchronized (death) {
12797                while (who.isBinderAlive()) {
12798                    try {
12799                        death.wait();
12800                    } catch (InterruptedException e) {
12801                    }
12802                }
12803            }
12804            Watchdog.getInstance().setAllowRestart(true);
12805        }
12806    }
12807
12808    @Override
12809    public void restart() {
12810        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12811                != PackageManager.PERMISSION_GRANTED) {
12812            throw new SecurityException("Requires permission "
12813                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12814        }
12815
12816        Log.i(TAG, "Sending shutdown broadcast...");
12817
12818        BroadcastReceiver br = new BroadcastReceiver() {
12819            @Override public void onReceive(Context context, Intent intent) {
12820                // Now the broadcast is done, finish up the low-level shutdown.
12821                Log.i(TAG, "Shutting down activity manager...");
12822                shutdown(10000);
12823                Log.i(TAG, "Shutdown complete, restarting!");
12824                Process.killProcess(Process.myPid());
12825                System.exit(10);
12826            }
12827        };
12828
12829        // First send the high-level shut down broadcast.
12830        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12831        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12832        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12833        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12834        mContext.sendOrderedBroadcastAsUser(intent,
12835                UserHandle.ALL, null, br, mHandler, 0, null, null);
12836        */
12837        br.onReceive(mContext, intent);
12838    }
12839
12840    private long getLowRamTimeSinceIdle(long now) {
12841        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12842    }
12843
12844    @Override
12845    public void performIdleMaintenance() {
12846        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12847                != PackageManager.PERMISSION_GRANTED) {
12848            throw new SecurityException("Requires permission "
12849                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12850        }
12851
12852        synchronized (this) {
12853            final long now = SystemClock.uptimeMillis();
12854            final long timeSinceLastIdle = now - mLastIdleTime;
12855            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12856            mLastIdleTime = now;
12857            mLowRamTimeSinceLastIdle = 0;
12858            if (mLowRamStartTime != 0) {
12859                mLowRamStartTime = now;
12860            }
12861
12862            StringBuilder sb = new StringBuilder(128);
12863            sb.append("Idle maintenance over ");
12864            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12865            sb.append(" low RAM for ");
12866            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12867            Slog.i(TAG, sb.toString());
12868
12869            // If at least 1/3 of our time since the last idle period has been spent
12870            // with RAM low, then we want to kill processes.
12871            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12872
12873            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12874                ProcessRecord proc = mLruProcesses.get(i);
12875                if (proc.notCachedSinceIdle) {
12876                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12877                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12878                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12879                        if (doKilling && proc.initialIdlePss != 0
12880                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12881                            sb = new StringBuilder(128);
12882                            sb.append("Kill");
12883                            sb.append(proc.processName);
12884                            sb.append(" in idle maint: pss=");
12885                            sb.append(proc.lastPss);
12886                            sb.append(", swapPss=");
12887                            sb.append(proc.lastSwapPss);
12888                            sb.append(", initialPss=");
12889                            sb.append(proc.initialIdlePss);
12890                            sb.append(", period=");
12891                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12892                            sb.append(", lowRamPeriod=");
12893                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12894                            Slog.wtfQuiet(TAG, sb.toString());
12895                            proc.kill("idle maint (pss " + proc.lastPss
12896                                    + " from " + proc.initialIdlePss + ")", true);
12897                        }
12898                    }
12899                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12900                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12901                    proc.notCachedSinceIdle = true;
12902                    proc.initialIdlePss = 0;
12903                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12904                            mTestPssMode, isSleepingLocked(), now);
12905                }
12906            }
12907
12908            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12909            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12910        }
12911    }
12912
12913    @Override
12914    public void sendIdleJobTrigger() {
12915        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12916                != PackageManager.PERMISSION_GRANTED) {
12917            throw new SecurityException("Requires permission "
12918                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12919        }
12920
12921        final long ident = Binder.clearCallingIdentity();
12922        try {
12923            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12924                    .setPackage("android")
12925                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12926            broadcastIntent(null, intent, null, null, 0, null, null, null,
12927                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12928        } finally {
12929            Binder.restoreCallingIdentity(ident);
12930        }
12931    }
12932
12933    private void retrieveSettings() {
12934        final ContentResolver resolver = mContext.getContentResolver();
12935        final boolean freeformWindowManagement =
12936                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12937                        || Settings.Global.getInt(
12938                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12939        final boolean supportsPictureInPicture =
12940                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12941
12942        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12943        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12944        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12945        final boolean alwaysFinishActivities =
12946                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12947        final boolean lenientBackgroundCheck =
12948                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12949        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12950        final boolean forceResizable = Settings.Global.getInt(
12951                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12952        final boolean supportsLeanbackOnly =
12953                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12954
12955        // Transfer any global setting for forcing RTL layout, into a System Property
12956        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12957
12958        final Configuration configuration = new Configuration();
12959        Settings.System.getConfiguration(resolver, configuration);
12960        if (forceRtl) {
12961            // This will take care of setting the correct layout direction flags
12962            configuration.setLayoutDirection(configuration.locale);
12963        }
12964
12965        synchronized (this) {
12966            mDebugApp = mOrigDebugApp = debugApp;
12967            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12968            mAlwaysFinishActivities = alwaysFinishActivities;
12969            mLenientBackgroundCheck = lenientBackgroundCheck;
12970            mSupportsLeanbackOnly = supportsLeanbackOnly;
12971            mForceResizableActivities = forceResizable;
12972            if (supportsMultiWindow || forceResizable) {
12973                mSupportsMultiWindow = true;
12974                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12975                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12976            } else {
12977                mSupportsMultiWindow = false;
12978                mSupportsFreeformWindowManagement = false;
12979                mSupportsPictureInPicture = false;
12980            }
12981            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12982            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
12983            // This happens before any activities are started, so we can change global configuration
12984            // in-place.
12985            updateConfigurationLocked(configuration, null, true);
12986            final Configuration globalConfig = getGlobalConfiguration();
12987            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
12988
12989            // Load resources only after the current configuration has been set.
12990            final Resources res = mContext.getResources();
12991            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12992            mThumbnailWidth = res.getDimensionPixelSize(
12993                    com.android.internal.R.dimen.thumbnail_width);
12994            mThumbnailHeight = res.getDimensionPixelSize(
12995                    com.android.internal.R.dimen.thumbnail_height);
12996            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12997                    com.android.internal.R.string.config_appsNotReportingCrashes));
12998            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
12999                    com.android.internal.R.bool.config_customUserSwitchUi);
13000            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13001                mFullscreenThumbnailScale = (float) res
13002                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13003                    (float) globalConfig.screenWidthDp;
13004            } else {
13005                mFullscreenThumbnailScale = res.getFraction(
13006                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13007            }
13008        }
13009    }
13010
13011    public void systemReady(final Runnable goingCallback) {
13012        synchronized(this) {
13013            if (mSystemReady) {
13014                // If we're done calling all the receivers, run the next "boot phase" passed in
13015                // by the SystemServer
13016                if (goingCallback != null) {
13017                    goingCallback.run();
13018                }
13019                return;
13020            }
13021
13022            mLocalDeviceIdleController
13023                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13024
13025            // Make sure we have the current profile info, since it is needed for security checks.
13026            mUserController.onSystemReady();
13027            mRecentTasks.onSystemReadyLocked();
13028            mAppOpsService.systemReady();
13029            mSystemReady = true;
13030        }
13031
13032        ArrayList<ProcessRecord> procsToKill = null;
13033        synchronized(mPidsSelfLocked) {
13034            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13035                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13036                if (!isAllowedWhileBooting(proc.info)){
13037                    if (procsToKill == null) {
13038                        procsToKill = new ArrayList<ProcessRecord>();
13039                    }
13040                    procsToKill.add(proc);
13041                }
13042            }
13043        }
13044
13045        synchronized(this) {
13046            if (procsToKill != null) {
13047                for (int i=procsToKill.size()-1; i>=0; i--) {
13048                    ProcessRecord proc = procsToKill.get(i);
13049                    Slog.i(TAG, "Removing system update proc: " + proc);
13050                    removeProcessLocked(proc, true, false, "system update done");
13051                }
13052            }
13053
13054            // Now that we have cleaned up any update processes, we
13055            // are ready to start launching real processes and know that
13056            // we won't trample on them any more.
13057            mProcessesReady = true;
13058        }
13059
13060        Slog.i(TAG, "System now ready");
13061        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13062            SystemClock.uptimeMillis());
13063
13064        synchronized(this) {
13065            // Make sure we have no pre-ready processes sitting around.
13066
13067            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13068                ResolveInfo ri = mContext.getPackageManager()
13069                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13070                                STOCK_PM_FLAGS);
13071                CharSequence errorMsg = null;
13072                if (ri != null) {
13073                    ActivityInfo ai = ri.activityInfo;
13074                    ApplicationInfo app = ai.applicationInfo;
13075                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13076                        mTopAction = Intent.ACTION_FACTORY_TEST;
13077                        mTopData = null;
13078                        mTopComponent = new ComponentName(app.packageName,
13079                                ai.name);
13080                    } else {
13081                        errorMsg = mContext.getResources().getText(
13082                                com.android.internal.R.string.factorytest_not_system);
13083                    }
13084                } else {
13085                    errorMsg = mContext.getResources().getText(
13086                            com.android.internal.R.string.factorytest_no_action);
13087                }
13088                if (errorMsg != null) {
13089                    mTopAction = null;
13090                    mTopData = null;
13091                    mTopComponent = null;
13092                    Message msg = Message.obtain();
13093                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13094                    msg.getData().putCharSequence("msg", errorMsg);
13095                    mUiHandler.sendMessage(msg);
13096                }
13097            }
13098        }
13099
13100        retrieveSettings();
13101        final int currentUserId;
13102        synchronized (this) {
13103            currentUserId = mUserController.getCurrentUserIdLocked();
13104            readGrantedUriPermissionsLocked();
13105        }
13106
13107        if (goingCallback != null) goingCallback.run();
13108
13109        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13110                Integer.toString(currentUserId), currentUserId);
13111        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13112                Integer.toString(currentUserId), currentUserId);
13113        mSystemServiceManager.startUser(currentUserId);
13114
13115        synchronized (this) {
13116            // Only start up encryption-aware persistent apps; once user is
13117            // unlocked we'll come back around and start unaware apps
13118            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13119
13120            // Start up initial activity.
13121            mBooting = true;
13122            // Enable home activity for system user, so that the system can always boot. We don't
13123            // do this when the system user is not setup since the setup wizard should be the one
13124            // to handle home activity in this case.
13125            if (UserManager.isSplitSystemUser() &&
13126                    Settings.Secure.getInt(mContext.getContentResolver(),
13127                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13128                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13129                try {
13130                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13131                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13132                            UserHandle.USER_SYSTEM);
13133                } catch (RemoteException e) {
13134                    throw e.rethrowAsRuntimeException();
13135                }
13136            }
13137            startHomeActivityLocked(currentUserId, "systemReady");
13138
13139            try {
13140                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13141                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13142                            + " data partition or your device will be unstable.");
13143                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13144                }
13145            } catch (RemoteException e) {
13146            }
13147
13148            if (!Build.isBuildConsistent()) {
13149                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13150                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13151            }
13152
13153            long ident = Binder.clearCallingIdentity();
13154            try {
13155                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13156                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13157                        | Intent.FLAG_RECEIVER_FOREGROUND);
13158                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13159                broadcastIntentLocked(null, null, intent,
13160                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13161                        null, false, false, MY_PID, Process.SYSTEM_UID,
13162                        currentUserId);
13163                intent = new Intent(Intent.ACTION_USER_STARTING);
13164                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13165                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13166                broadcastIntentLocked(null, null, intent,
13167                        null, new IIntentReceiver.Stub() {
13168                            @Override
13169                            public void performReceive(Intent intent, int resultCode, String data,
13170                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13171                                    throws RemoteException {
13172                            }
13173                        }, 0, null, null,
13174                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13175                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13176            } catch (Throwable t) {
13177                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13178            } finally {
13179                Binder.restoreCallingIdentity(ident);
13180            }
13181            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13182            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13183        }
13184    }
13185
13186    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13187        synchronized (this) {
13188            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13189        }
13190    }
13191
13192    void skipCurrentReceiverLocked(ProcessRecord app) {
13193        for (BroadcastQueue queue : mBroadcastQueues) {
13194            queue.skipCurrentReceiverLocked(app);
13195        }
13196    }
13197
13198    /**
13199     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13200     * The application process will exit immediately after this call returns.
13201     * @param app object of the crashing app, null for the system server
13202     * @param crashInfo describing the exception
13203     */
13204    public void handleApplicationCrash(IBinder app,
13205            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13206        ProcessRecord r = findAppProcess(app, "Crash");
13207        final String processName = app == null ? "system_server"
13208                : (r == null ? "unknown" : r.processName);
13209
13210        handleApplicationCrashInner("crash", r, processName, crashInfo);
13211    }
13212
13213    /* Native crash reporting uses this inner version because it needs to be somewhat
13214     * decoupled from the AM-managed cleanup lifecycle
13215     */
13216    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13217            ApplicationErrorReport.CrashInfo crashInfo) {
13218        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13219                UserHandle.getUserId(Binder.getCallingUid()), processName,
13220                r == null ? -1 : r.info.flags,
13221                crashInfo.exceptionClassName,
13222                crashInfo.exceptionMessage,
13223                crashInfo.throwFileName,
13224                crashInfo.throwLineNumber);
13225
13226        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13227
13228        mAppErrors.crashApplication(r, crashInfo);
13229    }
13230
13231    public void handleApplicationStrictModeViolation(
13232            IBinder app,
13233            int violationMask,
13234            StrictMode.ViolationInfo info) {
13235        ProcessRecord r = findAppProcess(app, "StrictMode");
13236        if (r == null) {
13237            return;
13238        }
13239
13240        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13241            Integer stackFingerprint = info.hashCode();
13242            boolean logIt = true;
13243            synchronized (mAlreadyLoggedViolatedStacks) {
13244                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13245                    logIt = false;
13246                    // TODO: sub-sample into EventLog for these, with
13247                    // the info.durationMillis?  Then we'd get
13248                    // the relative pain numbers, without logging all
13249                    // the stack traces repeatedly.  We'd want to do
13250                    // likewise in the client code, which also does
13251                    // dup suppression, before the Binder call.
13252                } else {
13253                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13254                        mAlreadyLoggedViolatedStacks.clear();
13255                    }
13256                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13257                }
13258            }
13259            if (logIt) {
13260                logStrictModeViolationToDropBox(r, info);
13261            }
13262        }
13263
13264        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13265            AppErrorResult result = new AppErrorResult();
13266            synchronized (this) {
13267                final long origId = Binder.clearCallingIdentity();
13268
13269                Message msg = Message.obtain();
13270                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13271                HashMap<String, Object> data = new HashMap<String, Object>();
13272                data.put("result", result);
13273                data.put("app", r);
13274                data.put("violationMask", violationMask);
13275                data.put("info", info);
13276                msg.obj = data;
13277                mUiHandler.sendMessage(msg);
13278
13279                Binder.restoreCallingIdentity(origId);
13280            }
13281            int res = result.get();
13282            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13283        }
13284    }
13285
13286    // Depending on the policy in effect, there could be a bunch of
13287    // these in quick succession so we try to batch these together to
13288    // minimize disk writes, number of dropbox entries, and maximize
13289    // compression, by having more fewer, larger records.
13290    private void logStrictModeViolationToDropBox(
13291            ProcessRecord process,
13292            StrictMode.ViolationInfo info) {
13293        if (info == null) {
13294            return;
13295        }
13296        final boolean isSystemApp = process == null ||
13297                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13298                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13299        final String processName = process == null ? "unknown" : process.processName;
13300        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13301        final DropBoxManager dbox = (DropBoxManager)
13302                mContext.getSystemService(Context.DROPBOX_SERVICE);
13303
13304        // Exit early if the dropbox isn't configured to accept this report type.
13305        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13306
13307        boolean bufferWasEmpty;
13308        boolean needsFlush;
13309        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13310        synchronized (sb) {
13311            bufferWasEmpty = sb.length() == 0;
13312            appendDropBoxProcessHeaders(process, processName, sb);
13313            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13314            sb.append("System-App: ").append(isSystemApp).append("\n");
13315            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13316            if (info.violationNumThisLoop != 0) {
13317                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13318            }
13319            if (info.numAnimationsRunning != 0) {
13320                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13321            }
13322            if (info.broadcastIntentAction != null) {
13323                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13324            }
13325            if (info.durationMillis != -1) {
13326                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13327            }
13328            if (info.numInstances != -1) {
13329                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13330            }
13331            if (info.tags != null) {
13332                for (String tag : info.tags) {
13333                    sb.append("Span-Tag: ").append(tag).append("\n");
13334                }
13335            }
13336            sb.append("\n");
13337            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13338                sb.append(info.crashInfo.stackTrace);
13339                sb.append("\n");
13340            }
13341            if (info.message != null) {
13342                sb.append(info.message);
13343                sb.append("\n");
13344            }
13345
13346            // Only buffer up to ~64k.  Various logging bits truncate
13347            // things at 128k.
13348            needsFlush = (sb.length() > 64 * 1024);
13349        }
13350
13351        // Flush immediately if the buffer's grown too large, or this
13352        // is a non-system app.  Non-system apps are isolated with a
13353        // different tag & policy and not batched.
13354        //
13355        // Batching is useful during internal testing with
13356        // StrictMode settings turned up high.  Without batching,
13357        // thousands of separate files could be created on boot.
13358        if (!isSystemApp || needsFlush) {
13359            new Thread("Error dump: " + dropboxTag) {
13360                @Override
13361                public void run() {
13362                    String report;
13363                    synchronized (sb) {
13364                        report = sb.toString();
13365                        sb.delete(0, sb.length());
13366                        sb.trimToSize();
13367                    }
13368                    if (report.length() != 0) {
13369                        dbox.addText(dropboxTag, report);
13370                    }
13371                }
13372            }.start();
13373            return;
13374        }
13375
13376        // System app batching:
13377        if (!bufferWasEmpty) {
13378            // An existing dropbox-writing thread is outstanding, so
13379            // we don't need to start it up.  The existing thread will
13380            // catch the buffer appends we just did.
13381            return;
13382        }
13383
13384        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13385        // (After this point, we shouldn't access AMS internal data structures.)
13386        new Thread("Error dump: " + dropboxTag) {
13387            @Override
13388            public void run() {
13389                // 5 second sleep to let stacks arrive and be batched together
13390                try {
13391                    Thread.sleep(5000);  // 5 seconds
13392                } catch (InterruptedException e) {}
13393
13394                String errorReport;
13395                synchronized (mStrictModeBuffer) {
13396                    errorReport = mStrictModeBuffer.toString();
13397                    if (errorReport.length() == 0) {
13398                        return;
13399                    }
13400                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13401                    mStrictModeBuffer.trimToSize();
13402                }
13403                dbox.addText(dropboxTag, errorReport);
13404            }
13405        }.start();
13406    }
13407
13408    /**
13409     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13410     * @param app object of the crashing app, null for the system server
13411     * @param tag reported by the caller
13412     * @param system whether this wtf is coming from the system
13413     * @param crashInfo describing the context of the error
13414     * @return true if the process should exit immediately (WTF is fatal)
13415     */
13416    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13417            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13418        final int callingUid = Binder.getCallingUid();
13419        final int callingPid = Binder.getCallingPid();
13420
13421        if (system) {
13422            // If this is coming from the system, we could very well have low-level
13423            // system locks held, so we want to do this all asynchronously.  And we
13424            // never want this to become fatal, so there is that too.
13425            mHandler.post(new Runnable() {
13426                @Override public void run() {
13427                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13428                }
13429            });
13430            return false;
13431        }
13432
13433        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13434                crashInfo);
13435
13436        if (r != null && r.pid != Process.myPid() &&
13437                Settings.Global.getInt(mContext.getContentResolver(),
13438                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13439            mAppErrors.crashApplication(r, crashInfo);
13440            return true;
13441        } else {
13442            return false;
13443        }
13444    }
13445
13446    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13447            final ApplicationErrorReport.CrashInfo crashInfo) {
13448        final ProcessRecord r = findAppProcess(app, "WTF");
13449        final String processName = app == null ? "system_server"
13450                : (r == null ? "unknown" : r.processName);
13451
13452        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13453                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13454
13455        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13456
13457        return r;
13458    }
13459
13460    /**
13461     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13462     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13463     */
13464    private ProcessRecord findAppProcess(IBinder app, String reason) {
13465        if (app == null) {
13466            return null;
13467        }
13468
13469        synchronized (this) {
13470            final int NP = mProcessNames.getMap().size();
13471            for (int ip=0; ip<NP; ip++) {
13472                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13473                final int NA = apps.size();
13474                for (int ia=0; ia<NA; ia++) {
13475                    ProcessRecord p = apps.valueAt(ia);
13476                    if (p.thread != null && p.thread.asBinder() == app) {
13477                        return p;
13478                    }
13479                }
13480            }
13481
13482            Slog.w(TAG, "Can't find mystery application for " + reason
13483                    + " from pid=" + Binder.getCallingPid()
13484                    + " uid=" + Binder.getCallingUid() + ": " + app);
13485            return null;
13486        }
13487    }
13488
13489    /**
13490     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13491     * to append various headers to the dropbox log text.
13492     */
13493    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13494            StringBuilder sb) {
13495        // Watchdog thread ends up invoking this function (with
13496        // a null ProcessRecord) to add the stack file to dropbox.
13497        // Do not acquire a lock on this (am) in such cases, as it
13498        // could cause a potential deadlock, if and when watchdog
13499        // is invoked due to unavailability of lock on am and it
13500        // would prevent watchdog from killing system_server.
13501        if (process == null) {
13502            sb.append("Process: ").append(processName).append("\n");
13503            return;
13504        }
13505        // Note: ProcessRecord 'process' is guarded by the service
13506        // instance.  (notably process.pkgList, which could otherwise change
13507        // concurrently during execution of this method)
13508        synchronized (this) {
13509            sb.append("Process: ").append(processName).append("\n");
13510            int flags = process.info.flags;
13511            IPackageManager pm = AppGlobals.getPackageManager();
13512            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13513            for (int ip=0; ip<process.pkgList.size(); ip++) {
13514                String pkg = process.pkgList.keyAt(ip);
13515                sb.append("Package: ").append(pkg);
13516                try {
13517                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13518                    if (pi != null) {
13519                        sb.append(" v").append(pi.versionCode);
13520                        if (pi.versionName != null) {
13521                            sb.append(" (").append(pi.versionName).append(")");
13522                        }
13523                    }
13524                } catch (RemoteException e) {
13525                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13526                }
13527                sb.append("\n");
13528            }
13529        }
13530    }
13531
13532    private static String processClass(ProcessRecord process) {
13533        if (process == null || process.pid == MY_PID) {
13534            return "system_server";
13535        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13536            return "system_app";
13537        } else {
13538            return "data_app";
13539        }
13540    }
13541
13542    private volatile long mWtfClusterStart;
13543    private volatile int mWtfClusterCount;
13544
13545    /**
13546     * Write a description of an error (crash, WTF, ANR) to the drop box.
13547     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13548     * @param process which caused the error, null means the system server
13549     * @param activity which triggered the error, null if unknown
13550     * @param parent activity related to the error, null if unknown
13551     * @param subject line related to the error, null if absent
13552     * @param report in long form describing the error, null if absent
13553     * @param dataFile text file to include in the report, null if none
13554     * @param crashInfo giving an application stack trace, null if absent
13555     */
13556    public void addErrorToDropBox(String eventType,
13557            ProcessRecord process, String processName, ActivityRecord activity,
13558            ActivityRecord parent, String subject,
13559            final String report, final File dataFile,
13560            final ApplicationErrorReport.CrashInfo crashInfo) {
13561        // NOTE -- this must never acquire the ActivityManagerService lock,
13562        // otherwise the watchdog may be prevented from resetting the system.
13563
13564        // Bail early if not published yet
13565        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13566        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13567
13568        // Exit early if the dropbox isn't configured to accept this report type.
13569        final String dropboxTag = processClass(process) + "_" + eventType;
13570        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13571
13572        // Rate-limit how often we're willing to do the heavy lifting below to
13573        // collect and record logs; currently 5 logs per 10 second period.
13574        final long now = SystemClock.elapsedRealtime();
13575        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13576            mWtfClusterStart = now;
13577            mWtfClusterCount = 1;
13578        } else {
13579            if (mWtfClusterCount++ >= 5) return;
13580        }
13581
13582        final StringBuilder sb = new StringBuilder(1024);
13583        appendDropBoxProcessHeaders(process, processName, sb);
13584        if (process != null) {
13585            sb.append("Foreground: ")
13586                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13587                    .append("\n");
13588        }
13589        if (activity != null) {
13590            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13591        }
13592        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13593            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13594        }
13595        if (parent != null && parent != activity) {
13596            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13597        }
13598        if (subject != null) {
13599            sb.append("Subject: ").append(subject).append("\n");
13600        }
13601        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13602        if (Debug.isDebuggerConnected()) {
13603            sb.append("Debugger: Connected\n");
13604        }
13605        sb.append("\n");
13606
13607        // Do the rest in a worker thread to avoid blocking the caller on I/O
13608        // (After this point, we shouldn't access AMS internal data structures.)
13609        Thread worker = new Thread("Error dump: " + dropboxTag) {
13610            @Override
13611            public void run() {
13612                if (report != null) {
13613                    sb.append(report);
13614                }
13615
13616                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13617                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13618                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13619                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13620
13621                if (dataFile != null && maxDataFileSize > 0) {
13622                    try {
13623                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13624                                    "\n\n[[TRUNCATED]]"));
13625                    } catch (IOException e) {
13626                        Slog.e(TAG, "Error reading " + dataFile, e);
13627                    }
13628                }
13629                if (crashInfo != null && crashInfo.stackTrace != null) {
13630                    sb.append(crashInfo.stackTrace);
13631                }
13632
13633                if (lines > 0) {
13634                    sb.append("\n");
13635
13636                    // Merge several logcat streams, and take the last N lines
13637                    InputStreamReader input = null;
13638                    try {
13639                        java.lang.Process logcat = new ProcessBuilder(
13640                                "/system/bin/timeout", "-k", "15s", "10s",
13641                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13642                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13643                                        .redirectErrorStream(true).start();
13644
13645                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13646                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13647                        input = new InputStreamReader(logcat.getInputStream());
13648
13649                        int num;
13650                        char[] buf = new char[8192];
13651                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13652                    } catch (IOException e) {
13653                        Slog.e(TAG, "Error running logcat", e);
13654                    } finally {
13655                        if (input != null) try { input.close(); } catch (IOException e) {}
13656                    }
13657                }
13658
13659                dbox.addText(dropboxTag, sb.toString());
13660            }
13661        };
13662
13663        if (process == null) {
13664            // If process is null, we are being called from some internal code
13665            // and may be about to die -- run this synchronously.
13666            worker.run();
13667        } else {
13668            worker.start();
13669        }
13670    }
13671
13672    @Override
13673    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13674        enforceNotIsolatedCaller("getProcessesInErrorState");
13675        // assume our apps are happy - lazy create the list
13676        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13677
13678        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13679                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13680        int userId = UserHandle.getUserId(Binder.getCallingUid());
13681
13682        synchronized (this) {
13683
13684            // iterate across all processes
13685            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13686                ProcessRecord app = mLruProcesses.get(i);
13687                if (!allUsers && app.userId != userId) {
13688                    continue;
13689                }
13690                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13691                    // This one's in trouble, so we'll generate a report for it
13692                    // crashes are higher priority (in case there's a crash *and* an anr)
13693                    ActivityManager.ProcessErrorStateInfo report = null;
13694                    if (app.crashing) {
13695                        report = app.crashingReport;
13696                    } else if (app.notResponding) {
13697                        report = app.notRespondingReport;
13698                    }
13699
13700                    if (report != null) {
13701                        if (errList == null) {
13702                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13703                        }
13704                        errList.add(report);
13705                    } else {
13706                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13707                                " crashing = " + app.crashing +
13708                                " notResponding = " + app.notResponding);
13709                    }
13710                }
13711            }
13712        }
13713
13714        return errList;
13715    }
13716
13717    static int procStateToImportance(int procState, int memAdj,
13718            ActivityManager.RunningAppProcessInfo currApp) {
13719        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13720        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13721            currApp.lru = memAdj;
13722        } else {
13723            currApp.lru = 0;
13724        }
13725        return imp;
13726    }
13727
13728    private void fillInProcMemInfo(ProcessRecord app,
13729            ActivityManager.RunningAppProcessInfo outInfo) {
13730        outInfo.pid = app.pid;
13731        outInfo.uid = app.info.uid;
13732        if (mHeavyWeightProcess == app) {
13733            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13734        }
13735        if (app.persistent) {
13736            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13737        }
13738        if (app.activities.size() > 0) {
13739            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13740        }
13741        outInfo.lastTrimLevel = app.trimMemoryLevel;
13742        int adj = app.curAdj;
13743        int procState = app.curProcState;
13744        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13745        outInfo.importanceReasonCode = app.adjTypeCode;
13746        outInfo.processState = app.curProcState;
13747    }
13748
13749    @Override
13750    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13751        enforceNotIsolatedCaller("getRunningAppProcesses");
13752
13753        final int callingUid = Binder.getCallingUid();
13754
13755        // Lazy instantiation of list
13756        List<ActivityManager.RunningAppProcessInfo> runList = null;
13757        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13758                callingUid) == PackageManager.PERMISSION_GRANTED;
13759        final int userId = UserHandle.getUserId(callingUid);
13760        final boolean allUids = isGetTasksAllowed(
13761                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13762
13763        synchronized (this) {
13764            // Iterate across all processes
13765            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13766                ProcessRecord app = mLruProcesses.get(i);
13767                if ((!allUsers && app.userId != userId)
13768                        || (!allUids && app.uid != callingUid)) {
13769                    continue;
13770                }
13771                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13772                    // Generate process state info for running application
13773                    ActivityManager.RunningAppProcessInfo currApp =
13774                        new ActivityManager.RunningAppProcessInfo(app.processName,
13775                                app.pid, app.getPackageList());
13776                    fillInProcMemInfo(app, currApp);
13777                    if (app.adjSource instanceof ProcessRecord) {
13778                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13779                        currApp.importanceReasonImportance =
13780                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13781                                        app.adjSourceProcState);
13782                    } else if (app.adjSource instanceof ActivityRecord) {
13783                        ActivityRecord r = (ActivityRecord)app.adjSource;
13784                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13785                    }
13786                    if (app.adjTarget instanceof ComponentName) {
13787                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13788                    }
13789                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13790                    //        + " lru=" + currApp.lru);
13791                    if (runList == null) {
13792                        runList = new ArrayList<>();
13793                    }
13794                    runList.add(currApp);
13795                }
13796            }
13797        }
13798        return runList;
13799    }
13800
13801    @Override
13802    public List<ApplicationInfo> getRunningExternalApplications() {
13803        enforceNotIsolatedCaller("getRunningExternalApplications");
13804        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13805        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13806        if (runningApps != null && runningApps.size() > 0) {
13807            Set<String> extList = new HashSet<String>();
13808            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13809                if (app.pkgList != null) {
13810                    for (String pkg : app.pkgList) {
13811                        extList.add(pkg);
13812                    }
13813                }
13814            }
13815            IPackageManager pm = AppGlobals.getPackageManager();
13816            for (String pkg : extList) {
13817                try {
13818                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13819                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13820                        retList.add(info);
13821                    }
13822                } catch (RemoteException e) {
13823                }
13824            }
13825        }
13826        return retList;
13827    }
13828
13829    @Override
13830    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13831        enforceNotIsolatedCaller("getMyMemoryState");
13832        synchronized (this) {
13833            ProcessRecord proc;
13834            synchronized (mPidsSelfLocked) {
13835                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13836            }
13837            fillInProcMemInfo(proc, outInfo);
13838        }
13839    }
13840
13841    @Override
13842    public int getMemoryTrimLevel() {
13843        enforceNotIsolatedCaller("getMyMemoryState");
13844        synchronized (this) {
13845            return mLastMemoryLevel;
13846        }
13847    }
13848
13849    @Override
13850    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13851            FileDescriptor err, String[] args, ShellCallback callback,
13852            ResultReceiver resultReceiver) {
13853        (new ActivityManagerShellCommand(this, false)).exec(
13854                this, in, out, err, args, callback, resultReceiver);
13855    }
13856
13857    @Override
13858    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13859        if (checkCallingPermission(android.Manifest.permission.DUMP)
13860                != PackageManager.PERMISSION_GRANTED) {
13861            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13862                    + Binder.getCallingPid()
13863                    + ", uid=" + Binder.getCallingUid()
13864                    + " without permission "
13865                    + android.Manifest.permission.DUMP);
13866            return;
13867        }
13868
13869        boolean dumpAll = false;
13870        boolean dumpClient = false;
13871        boolean dumpCheckin = false;
13872        boolean dumpCheckinFormat = false;
13873        boolean dumpVisibleStacks = false;
13874        String dumpPackage = null;
13875
13876        int opti = 0;
13877        while (opti < args.length) {
13878            String opt = args[opti];
13879            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13880                break;
13881            }
13882            opti++;
13883            if ("-a".equals(opt)) {
13884                dumpAll = true;
13885            } else if ("-c".equals(opt)) {
13886                dumpClient = true;
13887            } else if ("-v".equals(opt)) {
13888                dumpVisibleStacks = true;
13889            } else if ("-p".equals(opt)) {
13890                if (opti < args.length) {
13891                    dumpPackage = args[opti];
13892                    opti++;
13893                } else {
13894                    pw.println("Error: -p option requires package argument");
13895                    return;
13896                }
13897                dumpClient = true;
13898            } else if ("--checkin".equals(opt)) {
13899                dumpCheckin = dumpCheckinFormat = true;
13900            } else if ("-C".equals(opt)) {
13901                dumpCheckinFormat = true;
13902            } else if ("-h".equals(opt)) {
13903                ActivityManagerShellCommand.dumpHelp(pw, true);
13904                return;
13905            } else {
13906                pw.println("Unknown argument: " + opt + "; use -h for help");
13907            }
13908        }
13909
13910        long origId = Binder.clearCallingIdentity();
13911        boolean more = false;
13912        // Is the caller requesting to dump a particular piece of data?
13913        if (opti < args.length) {
13914            String cmd = args[opti];
13915            opti++;
13916            if ("activities".equals(cmd) || "a".equals(cmd)) {
13917                synchronized (this) {
13918                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13919                }
13920            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13921                synchronized (this) {
13922                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13923                }
13924            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13925                String[] newArgs;
13926                String name;
13927                if (opti >= args.length) {
13928                    name = null;
13929                    newArgs = EMPTY_STRING_ARRAY;
13930                } else {
13931                    dumpPackage = args[opti];
13932                    opti++;
13933                    newArgs = new String[args.length - opti];
13934                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13935                            args.length - opti);
13936                }
13937                synchronized (this) {
13938                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13939                }
13940            } else if ("broadcast-stats".equals(cmd)) {
13941                String[] newArgs;
13942                String name;
13943                if (opti >= args.length) {
13944                    name = null;
13945                    newArgs = EMPTY_STRING_ARRAY;
13946                } else {
13947                    dumpPackage = args[opti];
13948                    opti++;
13949                    newArgs = new String[args.length - opti];
13950                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13951                            args.length - opti);
13952                }
13953                synchronized (this) {
13954                    if (dumpCheckinFormat) {
13955                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13956                                dumpPackage);
13957                    } else {
13958                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13959                    }
13960                }
13961            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13962                String[] newArgs;
13963                String name;
13964                if (opti >= args.length) {
13965                    name = null;
13966                    newArgs = EMPTY_STRING_ARRAY;
13967                } else {
13968                    dumpPackage = args[opti];
13969                    opti++;
13970                    newArgs = new String[args.length - opti];
13971                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13972                            args.length - opti);
13973                }
13974                synchronized (this) {
13975                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13976                }
13977            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13978                String[] newArgs;
13979                String name;
13980                if (opti >= args.length) {
13981                    name = null;
13982                    newArgs = EMPTY_STRING_ARRAY;
13983                } else {
13984                    dumpPackage = args[opti];
13985                    opti++;
13986                    newArgs = new String[args.length - opti];
13987                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13988                            args.length - opti);
13989                }
13990                synchronized (this) {
13991                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13992                }
13993            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13994                synchronized (this) {
13995                    dumpOomLocked(fd, pw, args, opti, true);
13996                }
13997            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13998                synchronized (this) {
13999                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14000                }
14001            } else if ("provider".equals(cmd)) {
14002                String[] newArgs;
14003                String name;
14004                if (opti >= args.length) {
14005                    name = null;
14006                    newArgs = EMPTY_STRING_ARRAY;
14007                } else {
14008                    name = args[opti];
14009                    opti++;
14010                    newArgs = new String[args.length - opti];
14011                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14012                }
14013                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14014                    pw.println("No providers match: " + name);
14015                    pw.println("Use -h for help.");
14016                }
14017            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14018                synchronized (this) {
14019                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14020                }
14021            } else if ("service".equals(cmd)) {
14022                String[] newArgs;
14023                String name;
14024                if (opti >= args.length) {
14025                    name = null;
14026                    newArgs = EMPTY_STRING_ARRAY;
14027                } else {
14028                    name = args[opti];
14029                    opti++;
14030                    newArgs = new String[args.length - opti];
14031                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14032                            args.length - opti);
14033                }
14034                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14035                    pw.println("No services match: " + name);
14036                    pw.println("Use -h for help.");
14037                }
14038            } else if ("package".equals(cmd)) {
14039                String[] newArgs;
14040                if (opti >= args.length) {
14041                    pw.println("package: no package name specified");
14042                    pw.println("Use -h for help.");
14043                } else {
14044                    dumpPackage = args[opti];
14045                    opti++;
14046                    newArgs = new String[args.length - opti];
14047                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14048                            args.length - opti);
14049                    args = newArgs;
14050                    opti = 0;
14051                    more = true;
14052                }
14053            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14054                synchronized (this) {
14055                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14056                }
14057            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14058                if (dumpClient) {
14059                    ActiveServices.ServiceDumper dumper;
14060                    synchronized (this) {
14061                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14062                                dumpPackage);
14063                    }
14064                    dumper.dumpWithClient();
14065                } else {
14066                    synchronized (this) {
14067                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14068                                dumpPackage).dumpLocked();
14069                    }
14070                }
14071            } else if ("locks".equals(cmd)) {
14072                LockGuard.dump(fd, pw, args);
14073            } else {
14074                // Dumping a single activity?
14075                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14076                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14077                    int res = shell.exec(this, null, fd, null, args, null,
14078                            new ResultReceiver(null));
14079                    if (res < 0) {
14080                        pw.println("Bad activity command, or no activities match: " + cmd);
14081                        pw.println("Use -h for help.");
14082                    }
14083                }
14084            }
14085            if (!more) {
14086                Binder.restoreCallingIdentity(origId);
14087                return;
14088            }
14089        }
14090
14091        // No piece of data specified, dump everything.
14092        if (dumpCheckinFormat) {
14093            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14094        } else if (dumpClient) {
14095            ActiveServices.ServiceDumper sdumper;
14096            synchronized (this) {
14097                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14098                pw.println();
14099                if (dumpAll) {
14100                    pw.println("-------------------------------------------------------------------------------");
14101                }
14102                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14103                pw.println();
14104                if (dumpAll) {
14105                    pw.println("-------------------------------------------------------------------------------");
14106                }
14107                if (dumpAll || dumpPackage != null) {
14108                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14109                    pw.println();
14110                    if (dumpAll) {
14111                        pw.println("-------------------------------------------------------------------------------");
14112                    }
14113                }
14114                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14115                pw.println();
14116                if (dumpAll) {
14117                    pw.println("-------------------------------------------------------------------------------");
14118                }
14119                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14120                pw.println();
14121                if (dumpAll) {
14122                    pw.println("-------------------------------------------------------------------------------");
14123                }
14124                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14125                        dumpPackage);
14126            }
14127            sdumper.dumpWithClient();
14128            pw.println();
14129            synchronized (this) {
14130                if (dumpAll) {
14131                    pw.println("-------------------------------------------------------------------------------");
14132                }
14133                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14134                pw.println();
14135                if (dumpAll) {
14136                    pw.println("-------------------------------------------------------------------------------");
14137                }
14138                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14139                if (mAssociations.size() > 0) {
14140                    pw.println();
14141                    if (dumpAll) {
14142                        pw.println("-------------------------------------------------------------------------------");
14143                    }
14144                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14145                }
14146                pw.println();
14147                if (dumpAll) {
14148                    pw.println("-------------------------------------------------------------------------------");
14149                }
14150                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14151            }
14152
14153        } else {
14154            synchronized (this) {
14155                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14156                pw.println();
14157                if (dumpAll) {
14158                    pw.println("-------------------------------------------------------------------------------");
14159                }
14160                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14161                pw.println();
14162                if (dumpAll) {
14163                    pw.println("-------------------------------------------------------------------------------");
14164                }
14165                if (dumpAll || dumpPackage != null) {
14166                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14167                    pw.println();
14168                    if (dumpAll) {
14169                        pw.println("-------------------------------------------------------------------------------");
14170                    }
14171                }
14172                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14173                pw.println();
14174                if (dumpAll) {
14175                    pw.println("-------------------------------------------------------------------------------");
14176                }
14177                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14178                pw.println();
14179                if (dumpAll) {
14180                    pw.println("-------------------------------------------------------------------------------");
14181                }
14182                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14183                        .dumpLocked();
14184                pw.println();
14185                if (dumpAll) {
14186                    pw.println("-------------------------------------------------------------------------------");
14187                }
14188                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14189                pw.println();
14190                if (dumpAll) {
14191                    pw.println("-------------------------------------------------------------------------------");
14192                }
14193                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14194                if (mAssociations.size() > 0) {
14195                    pw.println();
14196                    if (dumpAll) {
14197                        pw.println("-------------------------------------------------------------------------------");
14198                    }
14199                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14200                }
14201                pw.println();
14202                if (dumpAll) {
14203                    pw.println("-------------------------------------------------------------------------------");
14204                }
14205                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14206            }
14207        }
14208        Binder.restoreCallingIdentity(origId);
14209    }
14210
14211    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14212            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14213        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14214
14215        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14216                dumpPackage);
14217        boolean needSep = printedAnything;
14218
14219        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14220                mStackSupervisor.getResumedActivityLocked(),
14221                dumpPackage, needSep, "  ResumedActivity: ");
14222        if (printed) {
14223            printedAnything = true;
14224            needSep = false;
14225        }
14226
14227        if (dumpPackage == null) {
14228            if (needSep) {
14229                pw.println();
14230            }
14231            needSep = true;
14232            printedAnything = true;
14233            mStackSupervisor.dump(pw, "  ");
14234        }
14235
14236        if (!printedAnything) {
14237            pw.println("  (nothing)");
14238        }
14239    }
14240
14241    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14242            int opti, boolean dumpAll, String dumpPackage) {
14243        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14244
14245        boolean printedAnything = false;
14246
14247        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14248            boolean printedHeader = false;
14249
14250            final int N = mRecentTasks.size();
14251            for (int i=0; i<N; i++) {
14252                TaskRecord tr = mRecentTasks.get(i);
14253                if (dumpPackage != null) {
14254                    if (tr.realActivity == null ||
14255                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14256                        continue;
14257                    }
14258                }
14259                if (!printedHeader) {
14260                    pw.println("  Recent tasks:");
14261                    printedHeader = true;
14262                    printedAnything = true;
14263                }
14264                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14265                        pw.println(tr);
14266                if (dumpAll) {
14267                    mRecentTasks.get(i).dump(pw, "    ");
14268                }
14269            }
14270        }
14271
14272        if (!printedAnything) {
14273            pw.println("  (nothing)");
14274        }
14275    }
14276
14277    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14278            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14279        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14280
14281        int dumpUid = 0;
14282        if (dumpPackage != null) {
14283            IPackageManager pm = AppGlobals.getPackageManager();
14284            try {
14285                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14286            } catch (RemoteException e) {
14287            }
14288        }
14289
14290        boolean printedAnything = false;
14291
14292        final long now = SystemClock.uptimeMillis();
14293
14294        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14295            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14296                    = mAssociations.valueAt(i1);
14297            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14298                SparseArray<ArrayMap<String, Association>> sourceUids
14299                        = targetComponents.valueAt(i2);
14300                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14301                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14302                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14303                        Association ass = sourceProcesses.valueAt(i4);
14304                        if (dumpPackage != null) {
14305                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14306                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14307                                continue;
14308                            }
14309                        }
14310                        printedAnything = true;
14311                        pw.print("  ");
14312                        pw.print(ass.mTargetProcess);
14313                        pw.print("/");
14314                        UserHandle.formatUid(pw, ass.mTargetUid);
14315                        pw.print(" <- ");
14316                        pw.print(ass.mSourceProcess);
14317                        pw.print("/");
14318                        UserHandle.formatUid(pw, ass.mSourceUid);
14319                        pw.println();
14320                        pw.print("    via ");
14321                        pw.print(ass.mTargetComponent.flattenToShortString());
14322                        pw.println();
14323                        pw.print("    ");
14324                        long dur = ass.mTime;
14325                        if (ass.mNesting > 0) {
14326                            dur += now - ass.mStartTime;
14327                        }
14328                        TimeUtils.formatDuration(dur, pw);
14329                        pw.print(" (");
14330                        pw.print(ass.mCount);
14331                        pw.print(" times)");
14332                        pw.print("  ");
14333                        for (int i=0; i<ass.mStateTimes.length; i++) {
14334                            long amt = ass.mStateTimes[i];
14335                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14336                                amt += now - ass.mLastStateUptime;
14337                            }
14338                            if (amt != 0) {
14339                                pw.print(" ");
14340                                pw.print(ProcessList.makeProcStateString(
14341                                            i + ActivityManager.MIN_PROCESS_STATE));
14342                                pw.print("=");
14343                                TimeUtils.formatDuration(amt, pw);
14344                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14345                                    pw.print("*");
14346                                }
14347                            }
14348                        }
14349                        pw.println();
14350                        if (ass.mNesting > 0) {
14351                            pw.print("    Currently active: ");
14352                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14353                            pw.println();
14354                        }
14355                    }
14356                }
14357            }
14358
14359        }
14360
14361        if (!printedAnything) {
14362            pw.println("  (nothing)");
14363        }
14364    }
14365
14366    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14367            String header, boolean needSep) {
14368        boolean printed = false;
14369        int whichAppId = -1;
14370        if (dumpPackage != null) {
14371            try {
14372                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14373                        dumpPackage, 0);
14374                whichAppId = UserHandle.getAppId(info.uid);
14375            } catch (NameNotFoundException e) {
14376                e.printStackTrace();
14377            }
14378        }
14379        for (int i=0; i<uids.size(); i++) {
14380            UidRecord uidRec = uids.valueAt(i);
14381            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14382                continue;
14383            }
14384            if (!printed) {
14385                printed = true;
14386                if (needSep) {
14387                    pw.println();
14388                }
14389                pw.print("  ");
14390                pw.println(header);
14391                needSep = true;
14392            }
14393            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14394            pw.print(": "); pw.println(uidRec);
14395        }
14396        return printed;
14397    }
14398
14399    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14400            int opti, boolean dumpAll, String dumpPackage) {
14401        boolean needSep = false;
14402        boolean printedAnything = false;
14403        int numPers = 0;
14404
14405        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14406
14407        if (dumpAll) {
14408            final int NP = mProcessNames.getMap().size();
14409            for (int ip=0; ip<NP; ip++) {
14410                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14411                final int NA = procs.size();
14412                for (int ia=0; ia<NA; ia++) {
14413                    ProcessRecord r = procs.valueAt(ia);
14414                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14415                        continue;
14416                    }
14417                    if (!needSep) {
14418                        pw.println("  All known processes:");
14419                        needSep = true;
14420                        printedAnything = true;
14421                    }
14422                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14423                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14424                        pw.print(" "); pw.println(r);
14425                    r.dump(pw, "    ");
14426                    if (r.persistent) {
14427                        numPers++;
14428                    }
14429                }
14430            }
14431        }
14432
14433        if (mIsolatedProcesses.size() > 0) {
14434            boolean printed = false;
14435            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14436                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14437                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14438                    continue;
14439                }
14440                if (!printed) {
14441                    if (needSep) {
14442                        pw.println();
14443                    }
14444                    pw.println("  Isolated process list (sorted by uid):");
14445                    printedAnything = true;
14446                    printed = true;
14447                    needSep = true;
14448                }
14449                pw.println(String.format("%sIsolated #%2d: %s",
14450                        "    ", i, r.toString()));
14451            }
14452        }
14453
14454        if (mActiveUids.size() > 0) {
14455            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14456                printedAnything = needSep = true;
14457            }
14458        }
14459        if (mValidateUids.size() > 0) {
14460            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14461                printedAnything = needSep = true;
14462            }
14463        }
14464
14465        if (mLruProcesses.size() > 0) {
14466            if (needSep) {
14467                pw.println();
14468            }
14469            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14470                    pw.print(" total, non-act at ");
14471                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14472                    pw.print(", non-svc at ");
14473                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14474                    pw.println("):");
14475            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14476            needSep = true;
14477            printedAnything = true;
14478        }
14479
14480        if (dumpAll || dumpPackage != null) {
14481            synchronized (mPidsSelfLocked) {
14482                boolean printed = false;
14483                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14484                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14485                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14486                        continue;
14487                    }
14488                    if (!printed) {
14489                        if (needSep) pw.println();
14490                        needSep = true;
14491                        pw.println("  PID mappings:");
14492                        printed = true;
14493                        printedAnything = true;
14494                    }
14495                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14496                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14497                }
14498            }
14499        }
14500
14501        if (mForegroundProcesses.size() > 0) {
14502            synchronized (mPidsSelfLocked) {
14503                boolean printed = false;
14504                for (int i=0; i<mForegroundProcesses.size(); i++) {
14505                    ProcessRecord r = mPidsSelfLocked.get(
14506                            mForegroundProcesses.valueAt(i).pid);
14507                    if (dumpPackage != null && (r == null
14508                            || !r.pkgList.containsKey(dumpPackage))) {
14509                        continue;
14510                    }
14511                    if (!printed) {
14512                        if (needSep) pw.println();
14513                        needSep = true;
14514                        pw.println("  Foreground Processes:");
14515                        printed = true;
14516                        printedAnything = true;
14517                    }
14518                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14519                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14520                }
14521            }
14522        }
14523
14524        if (mPersistentStartingProcesses.size() > 0) {
14525            if (needSep) pw.println();
14526            needSep = true;
14527            printedAnything = true;
14528            pw.println("  Persisent processes that are starting:");
14529            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14530                    "Starting Norm", "Restarting PERS", dumpPackage);
14531        }
14532
14533        if (mRemovedProcesses.size() > 0) {
14534            if (needSep) pw.println();
14535            needSep = true;
14536            printedAnything = true;
14537            pw.println("  Processes that are being removed:");
14538            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14539                    "Removed Norm", "Removed PERS", dumpPackage);
14540        }
14541
14542        if (mProcessesOnHold.size() > 0) {
14543            if (needSep) pw.println();
14544            needSep = true;
14545            printedAnything = true;
14546            pw.println("  Processes that are on old until the system is ready:");
14547            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14548                    "OnHold Norm", "OnHold PERS", dumpPackage);
14549        }
14550
14551        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14552
14553        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14554        if (needSep) {
14555            printedAnything = true;
14556        }
14557
14558        if (dumpPackage == null) {
14559            pw.println();
14560            needSep = false;
14561            mUserController.dump(pw, dumpAll);
14562        }
14563        if (mHomeProcess != null && (dumpPackage == null
14564                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14565            if (needSep) {
14566                pw.println();
14567                needSep = false;
14568            }
14569            pw.println("  mHomeProcess: " + mHomeProcess);
14570        }
14571        if (mPreviousProcess != null && (dumpPackage == null
14572                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14573            if (needSep) {
14574                pw.println();
14575                needSep = false;
14576            }
14577            pw.println("  mPreviousProcess: " + mPreviousProcess);
14578        }
14579        if (dumpAll) {
14580            StringBuilder sb = new StringBuilder(128);
14581            sb.append("  mPreviousProcessVisibleTime: ");
14582            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14583            pw.println(sb);
14584        }
14585        if (mHeavyWeightProcess != null && (dumpPackage == null
14586                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14587            if (needSep) {
14588                pw.println();
14589                needSep = false;
14590            }
14591            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14592        }
14593        if (dumpPackage == null) {
14594            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14595            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14596        }
14597        if (dumpAll) {
14598            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14599            if (mCompatModePackages.getPackages().size() > 0) {
14600                boolean printed = false;
14601                for (Map.Entry<String, Integer> entry
14602                        : mCompatModePackages.getPackages().entrySet()) {
14603                    String pkg = entry.getKey();
14604                    int mode = entry.getValue();
14605                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14606                        continue;
14607                    }
14608                    if (!printed) {
14609                        pw.println("  mScreenCompatPackages:");
14610                        printed = true;
14611                    }
14612                    pw.print("    "); pw.print(pkg); pw.print(": ");
14613                            pw.print(mode); pw.println();
14614                }
14615            }
14616        }
14617        if (dumpPackage == null) {
14618            pw.println("  mWakefulness="
14619                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14620            pw.println("  mSleepTokens=" + mSleepTokens);
14621            pw.println("  mSleeping=" + mSleeping);
14622            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14623            if (mRunningVoice != null) {
14624                pw.println("  mRunningVoice=" + mRunningVoice);
14625                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14626            }
14627        }
14628        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14629                || mOrigWaitForDebugger) {
14630            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14631                    || dumpPackage.equals(mOrigDebugApp)) {
14632                if (needSep) {
14633                    pw.println();
14634                    needSep = false;
14635                }
14636                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14637                        + " mDebugTransient=" + mDebugTransient
14638                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14639            }
14640        }
14641        if (mCurAppTimeTracker != null) {
14642            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14643        }
14644        if (mMemWatchProcesses.getMap().size() > 0) {
14645            pw.println("  Mem watch processes:");
14646            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14647                    = mMemWatchProcesses.getMap();
14648            for (int i=0; i<procs.size(); i++) {
14649                final String proc = procs.keyAt(i);
14650                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14651                for (int j=0; j<uids.size(); j++) {
14652                    if (needSep) {
14653                        pw.println();
14654                        needSep = false;
14655                    }
14656                    StringBuilder sb = new StringBuilder();
14657                    sb.append("    ").append(proc).append('/');
14658                    UserHandle.formatUid(sb, uids.keyAt(j));
14659                    Pair<Long, String> val = uids.valueAt(j);
14660                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14661                    if (val.second != null) {
14662                        sb.append(", report to ").append(val.second);
14663                    }
14664                    pw.println(sb.toString());
14665                }
14666            }
14667            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14668            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14669            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14670                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14671        }
14672        if (mTrackAllocationApp != null) {
14673            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14674                if (needSep) {
14675                    pw.println();
14676                    needSep = false;
14677                }
14678                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14679            }
14680        }
14681        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14682                || mProfileFd != null) {
14683            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14684                if (needSep) {
14685                    pw.println();
14686                    needSep = false;
14687                }
14688                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14689                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14690                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14691                        + mAutoStopProfiler);
14692                pw.println("  mProfileType=" + mProfileType);
14693            }
14694        }
14695        if (mNativeDebuggingApp != null) {
14696            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14697                if (needSep) {
14698                    pw.println();
14699                    needSep = false;
14700                }
14701                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14702            }
14703        }
14704        if (dumpPackage == null) {
14705            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14706                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14707                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14708            }
14709            if (mController != null) {
14710                pw.println("  mController=" + mController
14711                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14712            }
14713            if (dumpAll) {
14714                pw.println("  Total persistent processes: " + numPers);
14715                pw.println("  mProcessesReady=" + mProcessesReady
14716                        + " mSystemReady=" + mSystemReady
14717                        + " mBooted=" + mBooted
14718                        + " mFactoryTest=" + mFactoryTest);
14719                pw.println("  mBooting=" + mBooting
14720                        + " mCallFinishBooting=" + mCallFinishBooting
14721                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14722                pw.print("  mLastPowerCheckRealtime=");
14723                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14724                        pw.println("");
14725                pw.print("  mLastPowerCheckUptime=");
14726                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14727                        pw.println("");
14728                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14729                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14730                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14731                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14732                        + " (" + mLruProcesses.size() + " total)"
14733                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14734                        + " mNumServiceProcs=" + mNumServiceProcs
14735                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14736                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14737                        + " mLastMemoryLevel=" + mLastMemoryLevel
14738                        + " mLastNumProcesses=" + mLastNumProcesses);
14739                long now = SystemClock.uptimeMillis();
14740                pw.print("  mLastIdleTime=");
14741                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14742                        pw.print(" mLowRamSinceLastIdle=");
14743                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14744                        pw.println();
14745            }
14746        }
14747
14748        if (!printedAnything) {
14749            pw.println("  (nothing)");
14750        }
14751    }
14752
14753    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14754            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14755        if (mProcessesToGc.size() > 0) {
14756            boolean printed = false;
14757            long now = SystemClock.uptimeMillis();
14758            for (int i=0; i<mProcessesToGc.size(); i++) {
14759                ProcessRecord proc = mProcessesToGc.get(i);
14760                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14761                    continue;
14762                }
14763                if (!printed) {
14764                    if (needSep) pw.println();
14765                    needSep = true;
14766                    pw.println("  Processes that are waiting to GC:");
14767                    printed = true;
14768                }
14769                pw.print("    Process "); pw.println(proc);
14770                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14771                        pw.print(", last gced=");
14772                        pw.print(now-proc.lastRequestedGc);
14773                        pw.print(" ms ago, last lowMem=");
14774                        pw.print(now-proc.lastLowMemory);
14775                        pw.println(" ms ago");
14776
14777            }
14778        }
14779        return needSep;
14780    }
14781
14782    void printOomLevel(PrintWriter pw, String name, int adj) {
14783        pw.print("    ");
14784        if (adj >= 0) {
14785            pw.print(' ');
14786            if (adj < 10) pw.print(' ');
14787        } else {
14788            if (adj > -10) pw.print(' ');
14789        }
14790        pw.print(adj);
14791        pw.print(": ");
14792        pw.print(name);
14793        pw.print(" (");
14794        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14795        pw.println(")");
14796    }
14797
14798    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14799            int opti, boolean dumpAll) {
14800        boolean needSep = false;
14801
14802        if (mLruProcesses.size() > 0) {
14803            if (needSep) pw.println();
14804            needSep = true;
14805            pw.println("  OOM levels:");
14806            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14807            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14808            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14809            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14810            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14811            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14812            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14813            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14814            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14815            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14816            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14817            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14818            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14819            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14820
14821            if (needSep) pw.println();
14822            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14823                    pw.print(" total, non-act at ");
14824                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14825                    pw.print(", non-svc at ");
14826                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14827                    pw.println("):");
14828            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14829            needSep = true;
14830        }
14831
14832        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14833
14834        pw.println();
14835        pw.println("  mHomeProcess: " + mHomeProcess);
14836        pw.println("  mPreviousProcess: " + mPreviousProcess);
14837        if (mHeavyWeightProcess != null) {
14838            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14839        }
14840
14841        return true;
14842    }
14843
14844    /**
14845     * There are three ways to call this:
14846     *  - no provider specified: dump all the providers
14847     *  - a flattened component name that matched an existing provider was specified as the
14848     *    first arg: dump that one provider
14849     *  - the first arg isn't the flattened component name of an existing provider:
14850     *    dump all providers whose component contains the first arg as a substring
14851     */
14852    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14853            int opti, boolean dumpAll) {
14854        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14855    }
14856
14857    static class ItemMatcher {
14858        ArrayList<ComponentName> components;
14859        ArrayList<String> strings;
14860        ArrayList<Integer> objects;
14861        boolean all;
14862
14863        ItemMatcher() {
14864            all = true;
14865        }
14866
14867        void build(String name) {
14868            ComponentName componentName = ComponentName.unflattenFromString(name);
14869            if (componentName != null) {
14870                if (components == null) {
14871                    components = new ArrayList<ComponentName>();
14872                }
14873                components.add(componentName);
14874                all = false;
14875            } else {
14876                int objectId = 0;
14877                // Not a '/' separated full component name; maybe an object ID?
14878                try {
14879                    objectId = Integer.parseInt(name, 16);
14880                    if (objects == null) {
14881                        objects = new ArrayList<Integer>();
14882                    }
14883                    objects.add(objectId);
14884                    all = false;
14885                } catch (RuntimeException e) {
14886                    // Not an integer; just do string match.
14887                    if (strings == null) {
14888                        strings = new ArrayList<String>();
14889                    }
14890                    strings.add(name);
14891                    all = false;
14892                }
14893            }
14894        }
14895
14896        int build(String[] args, int opti) {
14897            for (; opti<args.length; opti++) {
14898                String name = args[opti];
14899                if ("--".equals(name)) {
14900                    return opti+1;
14901                }
14902                build(name);
14903            }
14904            return opti;
14905        }
14906
14907        boolean match(Object object, ComponentName comp) {
14908            if (all) {
14909                return true;
14910            }
14911            if (components != null) {
14912                for (int i=0; i<components.size(); i++) {
14913                    if (components.get(i).equals(comp)) {
14914                        return true;
14915                    }
14916                }
14917            }
14918            if (objects != null) {
14919                for (int i=0; i<objects.size(); i++) {
14920                    if (System.identityHashCode(object) == objects.get(i)) {
14921                        return true;
14922                    }
14923                }
14924            }
14925            if (strings != null) {
14926                String flat = comp.flattenToString();
14927                for (int i=0; i<strings.size(); i++) {
14928                    if (flat.contains(strings.get(i))) {
14929                        return true;
14930                    }
14931                }
14932            }
14933            return false;
14934        }
14935    }
14936
14937    /**
14938     * There are three things that cmd can be:
14939     *  - a flattened component name that matches an existing activity
14940     *  - the cmd arg isn't the flattened component name of an existing activity:
14941     *    dump all activity whose component contains the cmd as a substring
14942     *  - A hex number of the ActivityRecord object instance.
14943     */
14944    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14945            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
14946        ArrayList<ActivityRecord> activities;
14947
14948        synchronized (this) {
14949            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
14950        }
14951
14952        if (activities.size() <= 0) {
14953            return false;
14954        }
14955
14956        String[] newArgs = new String[args.length - opti];
14957        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14958
14959        TaskRecord lastTask = null;
14960        boolean needSep = false;
14961        for (int i=activities.size()-1; i>=0; i--) {
14962            ActivityRecord r = activities.get(i);
14963            if (needSep) {
14964                pw.println();
14965            }
14966            needSep = true;
14967            synchronized (this) {
14968                if (lastTask != r.task) {
14969                    lastTask = r.task;
14970                    pw.print("TASK "); pw.print(lastTask.affinity);
14971                            pw.print(" id="); pw.print(lastTask.taskId);
14972                            pw.print(" userId="); pw.println(lastTask.userId);
14973                    if (dumpAll) {
14974                        lastTask.dump(pw, "  ");
14975                    }
14976                }
14977            }
14978            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14979        }
14980        return true;
14981    }
14982
14983    /**
14984     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14985     * there is a thread associated with the activity.
14986     */
14987    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14988            final ActivityRecord r, String[] args, boolean dumpAll) {
14989        String innerPrefix = prefix + "  ";
14990        synchronized (this) {
14991            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14992                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14993                    pw.print(" pid=");
14994                    if (r.app != null) pw.println(r.app.pid);
14995                    else pw.println("(not running)");
14996            if (dumpAll) {
14997                r.dump(pw, innerPrefix);
14998            }
14999        }
15000        if (r.app != null && r.app.thread != null) {
15001            // flush anything that is already in the PrintWriter since the thread is going
15002            // to write to the file descriptor directly
15003            pw.flush();
15004            try {
15005                TransferPipe tp = new TransferPipe();
15006                try {
15007                    r.app.thread.dumpActivity(tp.getWriteFd(),
15008                            r.appToken, innerPrefix, args);
15009                    tp.go(fd);
15010                } finally {
15011                    tp.kill();
15012                }
15013            } catch (IOException e) {
15014                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15015            } catch (RemoteException e) {
15016                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15017            }
15018        }
15019    }
15020
15021    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15022            int opti, boolean dumpAll, String dumpPackage) {
15023        boolean needSep = false;
15024        boolean onlyHistory = false;
15025        boolean printedAnything = false;
15026
15027        if ("history".equals(dumpPackage)) {
15028            if (opti < args.length && "-s".equals(args[opti])) {
15029                dumpAll = false;
15030            }
15031            onlyHistory = true;
15032            dumpPackage = null;
15033        }
15034
15035        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15036        if (!onlyHistory && dumpAll) {
15037            if (mRegisteredReceivers.size() > 0) {
15038                boolean printed = false;
15039                Iterator it = mRegisteredReceivers.values().iterator();
15040                while (it.hasNext()) {
15041                    ReceiverList r = (ReceiverList)it.next();
15042                    if (dumpPackage != null && (r.app == null ||
15043                            !dumpPackage.equals(r.app.info.packageName))) {
15044                        continue;
15045                    }
15046                    if (!printed) {
15047                        pw.println("  Registered Receivers:");
15048                        needSep = true;
15049                        printed = true;
15050                        printedAnything = true;
15051                    }
15052                    pw.print("  * "); pw.println(r);
15053                    r.dump(pw, "    ");
15054                }
15055            }
15056
15057            if (mReceiverResolver.dump(pw, needSep ?
15058                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15059                    "    ", dumpPackage, false, false)) {
15060                needSep = true;
15061                printedAnything = true;
15062            }
15063        }
15064
15065        for (BroadcastQueue q : mBroadcastQueues) {
15066            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15067            printedAnything |= needSep;
15068        }
15069
15070        needSep = true;
15071
15072        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15073            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15074                if (needSep) {
15075                    pw.println();
15076                }
15077                needSep = true;
15078                printedAnything = true;
15079                pw.print("  Sticky broadcasts for user ");
15080                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15081                StringBuilder sb = new StringBuilder(128);
15082                for (Map.Entry<String, ArrayList<Intent>> ent
15083                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15084                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15085                    if (dumpAll) {
15086                        pw.println(":");
15087                        ArrayList<Intent> intents = ent.getValue();
15088                        final int N = intents.size();
15089                        for (int i=0; i<N; i++) {
15090                            sb.setLength(0);
15091                            sb.append("    Intent: ");
15092                            intents.get(i).toShortString(sb, false, true, false, false);
15093                            pw.println(sb.toString());
15094                            Bundle bundle = intents.get(i).getExtras();
15095                            if (bundle != null) {
15096                                pw.print("      ");
15097                                pw.println(bundle.toString());
15098                            }
15099                        }
15100                    } else {
15101                        pw.println("");
15102                    }
15103                }
15104            }
15105        }
15106
15107        if (!onlyHistory && dumpAll) {
15108            pw.println();
15109            for (BroadcastQueue queue : mBroadcastQueues) {
15110                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15111                        + queue.mBroadcastsScheduled);
15112            }
15113            pw.println("  mHandler:");
15114            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15115            needSep = true;
15116            printedAnything = true;
15117        }
15118
15119        if (!printedAnything) {
15120            pw.println("  (nothing)");
15121        }
15122    }
15123
15124    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15125            int opti, boolean dumpAll, String dumpPackage) {
15126        if (mCurBroadcastStats == null) {
15127            return;
15128        }
15129
15130        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15131        final long now = SystemClock.elapsedRealtime();
15132        if (mLastBroadcastStats != null) {
15133            pw.print("  Last stats (from ");
15134            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15135            pw.print(" to ");
15136            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15137            pw.print(", ");
15138            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15139                    - mLastBroadcastStats.mStartUptime, pw);
15140            pw.println(" uptime):");
15141            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15142                pw.println("    (nothing)");
15143            }
15144            pw.println();
15145        }
15146        pw.print("  Current stats (from ");
15147        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15148        pw.print(" to now, ");
15149        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15150                - mCurBroadcastStats.mStartUptime, pw);
15151        pw.println(" uptime):");
15152        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15153            pw.println("    (nothing)");
15154        }
15155    }
15156
15157    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15158            int opti, boolean fullCheckin, String dumpPackage) {
15159        if (mCurBroadcastStats == null) {
15160            return;
15161        }
15162
15163        if (mLastBroadcastStats != null) {
15164            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15165            if (fullCheckin) {
15166                mLastBroadcastStats = null;
15167                return;
15168            }
15169        }
15170        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15171        if (fullCheckin) {
15172            mCurBroadcastStats = null;
15173        }
15174    }
15175
15176    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15177            int opti, boolean dumpAll, String dumpPackage) {
15178        boolean needSep;
15179        boolean printedAnything = false;
15180
15181        ItemMatcher matcher = new ItemMatcher();
15182        matcher.build(args, opti);
15183
15184        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15185
15186        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15187        printedAnything |= needSep;
15188
15189        if (mLaunchingProviders.size() > 0) {
15190            boolean printed = false;
15191            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15192                ContentProviderRecord r = mLaunchingProviders.get(i);
15193                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15194                    continue;
15195                }
15196                if (!printed) {
15197                    if (needSep) pw.println();
15198                    needSep = true;
15199                    pw.println("  Launching content providers:");
15200                    printed = true;
15201                    printedAnything = true;
15202                }
15203                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15204                        pw.println(r);
15205            }
15206        }
15207
15208        if (!printedAnything) {
15209            pw.println("  (nothing)");
15210        }
15211    }
15212
15213    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15214            int opti, boolean dumpAll, String dumpPackage) {
15215        boolean needSep = false;
15216        boolean printedAnything = false;
15217
15218        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15219
15220        if (mGrantedUriPermissions.size() > 0) {
15221            boolean printed = false;
15222            int dumpUid = -2;
15223            if (dumpPackage != null) {
15224                try {
15225                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15226                            MATCH_UNINSTALLED_PACKAGES, 0);
15227                } catch (NameNotFoundException e) {
15228                    dumpUid = -1;
15229                }
15230            }
15231            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15232                int uid = mGrantedUriPermissions.keyAt(i);
15233                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15234                    continue;
15235                }
15236                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15237                if (!printed) {
15238                    if (needSep) pw.println();
15239                    needSep = true;
15240                    pw.println("  Granted Uri Permissions:");
15241                    printed = true;
15242                    printedAnything = true;
15243                }
15244                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15245                for (UriPermission perm : perms.values()) {
15246                    pw.print("    "); pw.println(perm);
15247                    if (dumpAll) {
15248                        perm.dump(pw, "      ");
15249                    }
15250                }
15251            }
15252        }
15253
15254        if (!printedAnything) {
15255            pw.println("  (nothing)");
15256        }
15257    }
15258
15259    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15260            int opti, boolean dumpAll, String dumpPackage) {
15261        boolean printed = false;
15262
15263        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15264
15265        if (mIntentSenderRecords.size() > 0) {
15266            Iterator<WeakReference<PendingIntentRecord>> it
15267                    = mIntentSenderRecords.values().iterator();
15268            while (it.hasNext()) {
15269                WeakReference<PendingIntentRecord> ref = it.next();
15270                PendingIntentRecord rec = ref != null ? ref.get(): null;
15271                if (dumpPackage != null && (rec == null
15272                        || !dumpPackage.equals(rec.key.packageName))) {
15273                    continue;
15274                }
15275                printed = true;
15276                if (rec != null) {
15277                    pw.print("  * "); pw.println(rec);
15278                    if (dumpAll) {
15279                        rec.dump(pw, "    ");
15280                    }
15281                } else {
15282                    pw.print("  * "); pw.println(ref);
15283                }
15284            }
15285        }
15286
15287        if (!printed) {
15288            pw.println("  (nothing)");
15289        }
15290    }
15291
15292    private static final int dumpProcessList(PrintWriter pw,
15293            ActivityManagerService service, List list,
15294            String prefix, String normalLabel, String persistentLabel,
15295            String dumpPackage) {
15296        int numPers = 0;
15297        final int N = list.size()-1;
15298        for (int i=N; i>=0; i--) {
15299            ProcessRecord r = (ProcessRecord)list.get(i);
15300            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15301                continue;
15302            }
15303            pw.println(String.format("%s%s #%2d: %s",
15304                    prefix, (r.persistent ? persistentLabel : normalLabel),
15305                    i, r.toString()));
15306            if (r.persistent) {
15307                numPers++;
15308            }
15309        }
15310        return numPers;
15311    }
15312
15313    private static final boolean dumpProcessOomList(PrintWriter pw,
15314            ActivityManagerService service, List<ProcessRecord> origList,
15315            String prefix, String normalLabel, String persistentLabel,
15316            boolean inclDetails, String dumpPackage) {
15317
15318        ArrayList<Pair<ProcessRecord, Integer>> list
15319                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15320        for (int i=0; i<origList.size(); i++) {
15321            ProcessRecord r = origList.get(i);
15322            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15323                continue;
15324            }
15325            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15326        }
15327
15328        if (list.size() <= 0) {
15329            return false;
15330        }
15331
15332        Comparator<Pair<ProcessRecord, Integer>> comparator
15333                = new Comparator<Pair<ProcessRecord, Integer>>() {
15334            @Override
15335            public int compare(Pair<ProcessRecord, Integer> object1,
15336                    Pair<ProcessRecord, Integer> object2) {
15337                if (object1.first.setAdj != object2.first.setAdj) {
15338                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15339                }
15340                if (object1.first.setProcState != object2.first.setProcState) {
15341                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15342                }
15343                if (object1.second.intValue() != object2.second.intValue()) {
15344                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15345                }
15346                return 0;
15347            }
15348        };
15349
15350        Collections.sort(list, comparator);
15351
15352        final long curRealtime = SystemClock.elapsedRealtime();
15353        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15354        final long curUptime = SystemClock.uptimeMillis();
15355        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15356
15357        for (int i=list.size()-1; i>=0; i--) {
15358            ProcessRecord r = list.get(i).first;
15359            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15360            char schedGroup;
15361            switch (r.setSchedGroup) {
15362                case ProcessList.SCHED_GROUP_BACKGROUND:
15363                    schedGroup = 'B';
15364                    break;
15365                case ProcessList.SCHED_GROUP_DEFAULT:
15366                    schedGroup = 'F';
15367                    break;
15368                case ProcessList.SCHED_GROUP_TOP_APP:
15369                    schedGroup = 'T';
15370                    break;
15371                default:
15372                    schedGroup = '?';
15373                    break;
15374            }
15375            char foreground;
15376            if (r.foregroundActivities) {
15377                foreground = 'A';
15378            } else if (r.foregroundServices) {
15379                foreground = 'S';
15380            } else {
15381                foreground = ' ';
15382            }
15383            String procState = ProcessList.makeProcStateString(r.curProcState);
15384            pw.print(prefix);
15385            pw.print(r.persistent ? persistentLabel : normalLabel);
15386            pw.print(" #");
15387            int num = (origList.size()-1)-list.get(i).second;
15388            if (num < 10) pw.print(' ');
15389            pw.print(num);
15390            pw.print(": ");
15391            pw.print(oomAdj);
15392            pw.print(' ');
15393            pw.print(schedGroup);
15394            pw.print('/');
15395            pw.print(foreground);
15396            pw.print('/');
15397            pw.print(procState);
15398            pw.print(" trm:");
15399            if (r.trimMemoryLevel < 10) pw.print(' ');
15400            pw.print(r.trimMemoryLevel);
15401            pw.print(' ');
15402            pw.print(r.toShortString());
15403            pw.print(" (");
15404            pw.print(r.adjType);
15405            pw.println(')');
15406            if (r.adjSource != null || r.adjTarget != null) {
15407                pw.print(prefix);
15408                pw.print("    ");
15409                if (r.adjTarget instanceof ComponentName) {
15410                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15411                } else if (r.adjTarget != null) {
15412                    pw.print(r.adjTarget.toString());
15413                } else {
15414                    pw.print("{null}");
15415                }
15416                pw.print("<=");
15417                if (r.adjSource instanceof ProcessRecord) {
15418                    pw.print("Proc{");
15419                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15420                    pw.println("}");
15421                } else if (r.adjSource != null) {
15422                    pw.println(r.adjSource.toString());
15423                } else {
15424                    pw.println("{null}");
15425                }
15426            }
15427            if (inclDetails) {
15428                pw.print(prefix);
15429                pw.print("    ");
15430                pw.print("oom: max="); pw.print(r.maxAdj);
15431                pw.print(" curRaw="); pw.print(r.curRawAdj);
15432                pw.print(" setRaw="); pw.print(r.setRawAdj);
15433                pw.print(" cur="); pw.print(r.curAdj);
15434                pw.print(" set="); pw.println(r.setAdj);
15435                pw.print(prefix);
15436                pw.print("    ");
15437                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15438                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15439                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15440                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15441                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15442                pw.println();
15443                pw.print(prefix);
15444                pw.print("    ");
15445                pw.print("cached="); pw.print(r.cached);
15446                pw.print(" empty="); pw.print(r.empty);
15447                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15448
15449                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15450                    if (r.lastWakeTime != 0) {
15451                        long wtime;
15452                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15453                        synchronized (stats) {
15454                            wtime = stats.getProcessWakeTime(r.info.uid,
15455                                    r.pid, curRealtime);
15456                        }
15457                        long timeUsed = wtime - r.lastWakeTime;
15458                        pw.print(prefix);
15459                        pw.print("    ");
15460                        pw.print("keep awake over ");
15461                        TimeUtils.formatDuration(realtimeSince, pw);
15462                        pw.print(" used ");
15463                        TimeUtils.formatDuration(timeUsed, pw);
15464                        pw.print(" (");
15465                        pw.print((timeUsed*100)/realtimeSince);
15466                        pw.println("%)");
15467                    }
15468                    if (r.lastCpuTime != 0) {
15469                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15470                        pw.print(prefix);
15471                        pw.print("    ");
15472                        pw.print("run cpu over ");
15473                        TimeUtils.formatDuration(uptimeSince, pw);
15474                        pw.print(" used ");
15475                        TimeUtils.formatDuration(timeUsed, pw);
15476                        pw.print(" (");
15477                        pw.print((timeUsed*100)/uptimeSince);
15478                        pw.println("%)");
15479                    }
15480                }
15481            }
15482        }
15483        return true;
15484    }
15485
15486    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15487            String[] args) {
15488        ArrayList<ProcessRecord> procs;
15489        synchronized (this) {
15490            if (args != null && args.length > start
15491                    && args[start].charAt(0) != '-') {
15492                procs = new ArrayList<ProcessRecord>();
15493                int pid = -1;
15494                try {
15495                    pid = Integer.parseInt(args[start]);
15496                } catch (NumberFormatException e) {
15497                }
15498                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15499                    ProcessRecord proc = mLruProcesses.get(i);
15500                    if (proc.pid == pid) {
15501                        procs.add(proc);
15502                    } else if (allPkgs && proc.pkgList != null
15503                            && proc.pkgList.containsKey(args[start])) {
15504                        procs.add(proc);
15505                    } else if (proc.processName.equals(args[start])) {
15506                        procs.add(proc);
15507                    }
15508                }
15509                if (procs.size() <= 0) {
15510                    return null;
15511                }
15512            } else {
15513                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15514            }
15515        }
15516        return procs;
15517    }
15518
15519    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15520            PrintWriter pw, String[] args) {
15521        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15522        if (procs == null) {
15523            pw.println("No process found for: " + args[0]);
15524            return;
15525        }
15526
15527        long uptime = SystemClock.uptimeMillis();
15528        long realtime = SystemClock.elapsedRealtime();
15529        pw.println("Applications Graphics Acceleration Info:");
15530        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15531
15532        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15533            ProcessRecord r = procs.get(i);
15534            if (r.thread != null) {
15535                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15536                pw.flush();
15537                try {
15538                    TransferPipe tp = new TransferPipe();
15539                    try {
15540                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15541                        tp.go(fd);
15542                    } finally {
15543                        tp.kill();
15544                    }
15545                } catch (IOException e) {
15546                    pw.println("Failure while dumping the app: " + r);
15547                    pw.flush();
15548                } catch (RemoteException e) {
15549                    pw.println("Got a RemoteException while dumping the app " + r);
15550                    pw.flush();
15551                }
15552            }
15553        }
15554    }
15555
15556    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15557        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15558        if (procs == null) {
15559            pw.println("No process found for: " + args[0]);
15560            return;
15561        }
15562
15563        pw.println("Applications Database Info:");
15564
15565        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15566            ProcessRecord r = procs.get(i);
15567            if (r.thread != null) {
15568                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15569                pw.flush();
15570                try {
15571                    TransferPipe tp = new TransferPipe();
15572                    try {
15573                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15574                        tp.go(fd);
15575                    } finally {
15576                        tp.kill();
15577                    }
15578                } catch (IOException e) {
15579                    pw.println("Failure while dumping the app: " + r);
15580                    pw.flush();
15581                } catch (RemoteException e) {
15582                    pw.println("Got a RemoteException while dumping the app " + r);
15583                    pw.flush();
15584                }
15585            }
15586        }
15587    }
15588
15589    final static class MemItem {
15590        final boolean isProc;
15591        final String label;
15592        final String shortLabel;
15593        final long pss;
15594        final long swapPss;
15595        final int id;
15596        final boolean hasActivities;
15597        ArrayList<MemItem> subitems;
15598
15599        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15600                boolean _hasActivities) {
15601            isProc = true;
15602            label = _label;
15603            shortLabel = _shortLabel;
15604            pss = _pss;
15605            swapPss = _swapPss;
15606            id = _id;
15607            hasActivities = _hasActivities;
15608        }
15609
15610        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15611            isProc = false;
15612            label = _label;
15613            shortLabel = _shortLabel;
15614            pss = _pss;
15615            swapPss = _swapPss;
15616            id = _id;
15617            hasActivities = false;
15618        }
15619    }
15620
15621    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15622            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15623        if (sort && !isCompact) {
15624            Collections.sort(items, new Comparator<MemItem>() {
15625                @Override
15626                public int compare(MemItem lhs, MemItem rhs) {
15627                    if (lhs.pss < rhs.pss) {
15628                        return 1;
15629                    } else if (lhs.pss > rhs.pss) {
15630                        return -1;
15631                    }
15632                    return 0;
15633                }
15634            });
15635        }
15636
15637        for (int i=0; i<items.size(); i++) {
15638            MemItem mi = items.get(i);
15639            if (!isCompact) {
15640                if (dumpSwapPss) {
15641                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15642                            mi.label, stringifyKBSize(mi.swapPss));
15643                } else {
15644                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15645                }
15646            } else if (mi.isProc) {
15647                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15648                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15649                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15650                pw.println(mi.hasActivities ? ",a" : ",e");
15651            } else {
15652                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15653                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15654            }
15655            if (mi.subitems != null) {
15656                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15657                        true, isCompact, dumpSwapPss);
15658            }
15659        }
15660    }
15661
15662    // These are in KB.
15663    static final long[] DUMP_MEM_BUCKETS = new long[] {
15664        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15665        120*1024, 160*1024, 200*1024,
15666        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15667        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15668    };
15669
15670    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15671            boolean stackLike) {
15672        int start = label.lastIndexOf('.');
15673        if (start >= 0) start++;
15674        else start = 0;
15675        int end = label.length();
15676        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15677            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15678                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15679                out.append(bucket);
15680                out.append(stackLike ? "MB." : "MB ");
15681                out.append(label, start, end);
15682                return;
15683            }
15684        }
15685        out.append(memKB/1024);
15686        out.append(stackLike ? "MB." : "MB ");
15687        out.append(label, start, end);
15688    }
15689
15690    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15691            ProcessList.NATIVE_ADJ,
15692            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15693            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15694            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15695            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15696            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15697            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15698    };
15699    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15700            "Native",
15701            "System", "Persistent", "Persistent Service", "Foreground",
15702            "Visible", "Perceptible",
15703            "Heavy Weight", "Backup",
15704            "A Services", "Home",
15705            "Previous", "B Services", "Cached"
15706    };
15707    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15708            "native",
15709            "sys", "pers", "persvc", "fore",
15710            "vis", "percept",
15711            "heavy", "backup",
15712            "servicea", "home",
15713            "prev", "serviceb", "cached"
15714    };
15715
15716    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15717            long realtime, boolean isCheckinRequest, boolean isCompact) {
15718        if (isCompact) {
15719            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15720        }
15721        if (isCheckinRequest || isCompact) {
15722            // short checkin version
15723            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15724        } else {
15725            pw.println("Applications Memory Usage (in Kilobytes):");
15726            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15727        }
15728    }
15729
15730    private static final int KSM_SHARED = 0;
15731    private static final int KSM_SHARING = 1;
15732    private static final int KSM_UNSHARED = 2;
15733    private static final int KSM_VOLATILE = 3;
15734
15735    private final long[] getKsmInfo() {
15736        long[] longOut = new long[4];
15737        final int[] SINGLE_LONG_FORMAT = new int[] {
15738            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15739        };
15740        long[] longTmp = new long[1];
15741        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15742                SINGLE_LONG_FORMAT, null, longTmp, null);
15743        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15744        longTmp[0] = 0;
15745        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15746                SINGLE_LONG_FORMAT, null, longTmp, null);
15747        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15748        longTmp[0] = 0;
15749        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15750                SINGLE_LONG_FORMAT, null, longTmp, null);
15751        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15752        longTmp[0] = 0;
15753        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15754                SINGLE_LONG_FORMAT, null, longTmp, null);
15755        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15756        return longOut;
15757    }
15758
15759    private static String stringifySize(long size, int order) {
15760        Locale locale = Locale.US;
15761        switch (order) {
15762            case 1:
15763                return String.format(locale, "%,13d", size);
15764            case 1024:
15765                return String.format(locale, "%,9dK", size / 1024);
15766            case 1024 * 1024:
15767                return String.format(locale, "%,5dM", size / 1024 / 1024);
15768            case 1024 * 1024 * 1024:
15769                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15770            default:
15771                throw new IllegalArgumentException("Invalid size order");
15772        }
15773    }
15774
15775    private static String stringifyKBSize(long size) {
15776        return stringifySize(size * 1024, 1024);
15777    }
15778
15779    // Update this version number in case you change the 'compact' format
15780    private static final int MEMINFO_COMPACT_VERSION = 1;
15781
15782    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15783            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15784        boolean dumpDetails = false;
15785        boolean dumpFullDetails = false;
15786        boolean dumpDalvik = false;
15787        boolean dumpSummaryOnly = false;
15788        boolean dumpUnreachable = false;
15789        boolean oomOnly = false;
15790        boolean isCompact = false;
15791        boolean localOnly = false;
15792        boolean packages = false;
15793        boolean isCheckinRequest = false;
15794        boolean dumpSwapPss = false;
15795
15796        int opti = 0;
15797        while (opti < args.length) {
15798            String opt = args[opti];
15799            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15800                break;
15801            }
15802            opti++;
15803            if ("-a".equals(opt)) {
15804                dumpDetails = true;
15805                dumpFullDetails = true;
15806                dumpDalvik = true;
15807                dumpSwapPss = true;
15808            } else if ("-d".equals(opt)) {
15809                dumpDalvik = true;
15810            } else if ("-c".equals(opt)) {
15811                isCompact = true;
15812            } else if ("-s".equals(opt)) {
15813                dumpDetails = true;
15814                dumpSummaryOnly = true;
15815            } else if ("-S".equals(opt)) {
15816                dumpSwapPss = true;
15817            } else if ("--unreachable".equals(opt)) {
15818                dumpUnreachable = true;
15819            } else if ("--oom".equals(opt)) {
15820                oomOnly = true;
15821            } else if ("--local".equals(opt)) {
15822                localOnly = true;
15823            } else if ("--package".equals(opt)) {
15824                packages = true;
15825            } else if ("--checkin".equals(opt)) {
15826                isCheckinRequest = true;
15827
15828            } else if ("-h".equals(opt)) {
15829                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15830                pw.println("  -a: include all available information for each process.");
15831                pw.println("  -d: include dalvik details.");
15832                pw.println("  -c: dump in a compact machine-parseable representation.");
15833                pw.println("  -s: dump only summary of application memory usage.");
15834                pw.println("  -S: dump also SwapPss.");
15835                pw.println("  --oom: only show processes organized by oom adj.");
15836                pw.println("  --local: only collect details locally, don't call process.");
15837                pw.println("  --package: interpret process arg as package, dumping all");
15838                pw.println("             processes that have loaded that package.");
15839                pw.println("  --checkin: dump data for a checkin");
15840                pw.println("If [process] is specified it can be the name or ");
15841                pw.println("pid of a specific process to dump.");
15842                return;
15843            } else {
15844                pw.println("Unknown argument: " + opt + "; use -h for help");
15845            }
15846        }
15847
15848        long uptime = SystemClock.uptimeMillis();
15849        long realtime = SystemClock.elapsedRealtime();
15850        final long[] tmpLong = new long[1];
15851
15852        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15853        if (procs == null) {
15854            // No Java processes.  Maybe they want to print a native process.
15855            if (args != null && args.length > opti
15856                    && args[opti].charAt(0) != '-') {
15857                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15858                        = new ArrayList<ProcessCpuTracker.Stats>();
15859                updateCpuStatsNow();
15860                int findPid = -1;
15861                try {
15862                    findPid = Integer.parseInt(args[opti]);
15863                } catch (NumberFormatException e) {
15864                }
15865                synchronized (mProcessCpuTracker) {
15866                    final int N = mProcessCpuTracker.countStats();
15867                    for (int i=0; i<N; i++) {
15868                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15869                        if (st.pid == findPid || (st.baseName != null
15870                                && st.baseName.equals(args[opti]))) {
15871                            nativeProcs.add(st);
15872                        }
15873                    }
15874                }
15875                if (nativeProcs.size() > 0) {
15876                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15877                            isCompact);
15878                    Debug.MemoryInfo mi = null;
15879                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15880                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15881                        final int pid = r.pid;
15882                        if (!isCheckinRequest && dumpDetails) {
15883                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15884                        }
15885                        if (mi == null) {
15886                            mi = new Debug.MemoryInfo();
15887                        }
15888                        if (dumpDetails || (!brief && !oomOnly)) {
15889                            Debug.getMemoryInfo(pid, mi);
15890                        } else {
15891                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15892                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15893                        }
15894                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15895                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15896                        if (isCheckinRequest) {
15897                            pw.println();
15898                        }
15899                    }
15900                    return;
15901                }
15902            }
15903            pw.println("No process found for: " + args[opti]);
15904            return;
15905        }
15906
15907        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15908            dumpDetails = true;
15909        }
15910
15911        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15912
15913        String[] innerArgs = new String[args.length-opti];
15914        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15915
15916        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15917        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15918        long nativePss = 0;
15919        long nativeSwapPss = 0;
15920        long dalvikPss = 0;
15921        long dalvikSwapPss = 0;
15922        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15923                EmptyArray.LONG;
15924        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15925                EmptyArray.LONG;
15926        long otherPss = 0;
15927        long otherSwapPss = 0;
15928        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15929        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15930
15931        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15932        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15933        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15934                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15935
15936        long totalPss = 0;
15937        long totalSwapPss = 0;
15938        long cachedPss = 0;
15939        long cachedSwapPss = 0;
15940        boolean hasSwapPss = false;
15941
15942        Debug.MemoryInfo mi = null;
15943        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15944            final ProcessRecord r = procs.get(i);
15945            final IApplicationThread thread;
15946            final int pid;
15947            final int oomAdj;
15948            final boolean hasActivities;
15949            synchronized (this) {
15950                thread = r.thread;
15951                pid = r.pid;
15952                oomAdj = r.getSetAdjWithServices();
15953                hasActivities = r.activities.size() > 0;
15954            }
15955            if (thread != null) {
15956                if (!isCheckinRequest && dumpDetails) {
15957                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15958                }
15959                if (mi == null) {
15960                    mi = new Debug.MemoryInfo();
15961                }
15962                if (dumpDetails || (!brief && !oomOnly)) {
15963                    Debug.getMemoryInfo(pid, mi);
15964                    hasSwapPss = mi.hasSwappedOutPss;
15965                } else {
15966                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15967                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15968                }
15969                if (dumpDetails) {
15970                    if (localOnly) {
15971                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15972                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15973                        if (isCheckinRequest) {
15974                            pw.println();
15975                        }
15976                    } else {
15977                        pw.flush();
15978                        try {
15979                            TransferPipe tp = new TransferPipe();
15980                            try {
15981                                thread.dumpMemInfo(tp.getWriteFd(),
15982                                        mi, isCheckinRequest, dumpFullDetails,
15983                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15984                                tp.go(fd);
15985                            } finally {
15986                                tp.kill();
15987                            }
15988                        } catch (IOException e) {
15989                            if (!isCheckinRequest) {
15990                                pw.println("Got IoException!");
15991                                pw.flush();
15992                            }
15993                        } catch (RemoteException e) {
15994                            if (!isCheckinRequest) {
15995                                pw.println("Got RemoteException!");
15996                                pw.flush();
15997                            }
15998                        }
15999                    }
16000                }
16001
16002                final long myTotalPss = mi.getTotalPss();
16003                final long myTotalUss = mi.getTotalUss();
16004                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16005
16006                synchronized (this) {
16007                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16008                        // Record this for posterity if the process has been stable.
16009                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16010                    }
16011                }
16012
16013                if (!isCheckinRequest && mi != null) {
16014                    totalPss += myTotalPss;
16015                    totalSwapPss += myTotalSwapPss;
16016                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16017                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16018                            myTotalSwapPss, pid, hasActivities);
16019                    procMems.add(pssItem);
16020                    procMemsMap.put(pid, pssItem);
16021
16022                    nativePss += mi.nativePss;
16023                    nativeSwapPss += mi.nativeSwappedOutPss;
16024                    dalvikPss += mi.dalvikPss;
16025                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16026                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16027                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16028                        dalvikSubitemSwapPss[j] +=
16029                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16030                    }
16031                    otherPss += mi.otherPss;
16032                    otherSwapPss += mi.otherSwappedOutPss;
16033                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16034                        long mem = mi.getOtherPss(j);
16035                        miscPss[j] += mem;
16036                        otherPss -= mem;
16037                        mem = mi.getOtherSwappedOutPss(j);
16038                        miscSwapPss[j] += mem;
16039                        otherSwapPss -= mem;
16040                    }
16041
16042                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16043                        cachedPss += myTotalPss;
16044                        cachedSwapPss += myTotalSwapPss;
16045                    }
16046
16047                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16048                        if (oomIndex == (oomPss.length - 1)
16049                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16050                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16051                            oomPss[oomIndex] += myTotalPss;
16052                            oomSwapPss[oomIndex] += myTotalSwapPss;
16053                            if (oomProcs[oomIndex] == null) {
16054                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16055                            }
16056                            oomProcs[oomIndex].add(pssItem);
16057                            break;
16058                        }
16059                    }
16060                }
16061            }
16062        }
16063
16064        long nativeProcTotalPss = 0;
16065
16066        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16067            // If we are showing aggregations, also look for native processes to
16068            // include so that our aggregations are more accurate.
16069            updateCpuStatsNow();
16070            mi = null;
16071            synchronized (mProcessCpuTracker) {
16072                final int N = mProcessCpuTracker.countStats();
16073                for (int i=0; i<N; i++) {
16074                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16075                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16076                        if (mi == null) {
16077                            mi = new Debug.MemoryInfo();
16078                        }
16079                        if (!brief && !oomOnly) {
16080                            Debug.getMemoryInfo(st.pid, mi);
16081                        } else {
16082                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16083                            mi.nativePrivateDirty = (int)tmpLong[0];
16084                        }
16085
16086                        final long myTotalPss = mi.getTotalPss();
16087                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16088                        totalPss += myTotalPss;
16089                        nativeProcTotalPss += myTotalPss;
16090
16091                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16092                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16093                        procMems.add(pssItem);
16094
16095                        nativePss += mi.nativePss;
16096                        nativeSwapPss += mi.nativeSwappedOutPss;
16097                        dalvikPss += mi.dalvikPss;
16098                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16099                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16100                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16101                            dalvikSubitemSwapPss[j] +=
16102                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16103                        }
16104                        otherPss += mi.otherPss;
16105                        otherSwapPss += mi.otherSwappedOutPss;
16106                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16107                            long mem = mi.getOtherPss(j);
16108                            miscPss[j] += mem;
16109                            otherPss -= mem;
16110                            mem = mi.getOtherSwappedOutPss(j);
16111                            miscSwapPss[j] += mem;
16112                            otherSwapPss -= mem;
16113                        }
16114                        oomPss[0] += myTotalPss;
16115                        oomSwapPss[0] += myTotalSwapPss;
16116                        if (oomProcs[0] == null) {
16117                            oomProcs[0] = new ArrayList<MemItem>();
16118                        }
16119                        oomProcs[0].add(pssItem);
16120                    }
16121                }
16122            }
16123
16124            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16125
16126            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16127            final MemItem dalvikItem =
16128                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16129            if (dalvikSubitemPss.length > 0) {
16130                dalvikItem.subitems = new ArrayList<MemItem>();
16131                for (int j=0; j<dalvikSubitemPss.length; j++) {
16132                    final String name = Debug.MemoryInfo.getOtherLabel(
16133                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16134                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16135                                    dalvikSubitemSwapPss[j], j));
16136                }
16137            }
16138            catMems.add(dalvikItem);
16139            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16140            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16141                String label = Debug.MemoryInfo.getOtherLabel(j);
16142                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16143            }
16144
16145            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16146            for (int j=0; j<oomPss.length; j++) {
16147                if (oomPss[j] != 0) {
16148                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16149                            : DUMP_MEM_OOM_LABEL[j];
16150                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16151                            DUMP_MEM_OOM_ADJ[j]);
16152                    item.subitems = oomProcs[j];
16153                    oomMems.add(item);
16154                }
16155            }
16156
16157            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16158            if (!brief && !oomOnly && !isCompact) {
16159                pw.println();
16160                pw.println("Total PSS by process:");
16161                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16162                pw.println();
16163            }
16164            if (!isCompact) {
16165                pw.println("Total PSS by OOM adjustment:");
16166            }
16167            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16168            if (!brief && !oomOnly) {
16169                PrintWriter out = categoryPw != null ? categoryPw : pw;
16170                if (!isCompact) {
16171                    out.println();
16172                    out.println("Total PSS by category:");
16173                }
16174                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16175            }
16176            if (!isCompact) {
16177                pw.println();
16178            }
16179            MemInfoReader memInfo = new MemInfoReader();
16180            memInfo.readMemInfo();
16181            if (nativeProcTotalPss > 0) {
16182                synchronized (this) {
16183                    final long cachedKb = memInfo.getCachedSizeKb();
16184                    final long freeKb = memInfo.getFreeSizeKb();
16185                    final long zramKb = memInfo.getZramTotalSizeKb();
16186                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16187                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16188                            kernelKb*1024, nativeProcTotalPss*1024);
16189                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16190                            nativeProcTotalPss);
16191                }
16192            }
16193            if (!brief) {
16194                if (!isCompact) {
16195                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16196                    pw.print(" (status ");
16197                    switch (mLastMemoryLevel) {
16198                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16199                            pw.println("normal)");
16200                            break;
16201                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16202                            pw.println("moderate)");
16203                            break;
16204                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16205                            pw.println("low)");
16206                            break;
16207                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16208                            pw.println("critical)");
16209                            break;
16210                        default:
16211                            pw.print(mLastMemoryLevel);
16212                            pw.println(")");
16213                            break;
16214                    }
16215                    pw.print(" Free RAM: ");
16216                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16217                            + memInfo.getFreeSizeKb()));
16218                    pw.print(" (");
16219                    pw.print(stringifyKBSize(cachedPss));
16220                    pw.print(" cached pss + ");
16221                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16222                    pw.print(" cached kernel + ");
16223                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16224                    pw.println(" free)");
16225                } else {
16226                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16227                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16228                            + memInfo.getFreeSizeKb()); pw.print(",");
16229                    pw.println(totalPss - cachedPss);
16230                }
16231            }
16232            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16233                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16234                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16235            if (!isCompact) {
16236                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16237                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16238                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16239                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16240                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16241            } else {
16242                pw.print("lostram,"); pw.println(lostRAM);
16243            }
16244            if (!brief) {
16245                if (memInfo.getZramTotalSizeKb() != 0) {
16246                    if (!isCompact) {
16247                        pw.print("     ZRAM: ");
16248                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16249                                pw.print(" physical used for ");
16250                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16251                                        - memInfo.getSwapFreeSizeKb()));
16252                                pw.print(" in swap (");
16253                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16254                                pw.println(" total swap)");
16255                    } else {
16256                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16257                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16258                                pw.println(memInfo.getSwapFreeSizeKb());
16259                    }
16260                }
16261                final long[] ksm = getKsmInfo();
16262                if (!isCompact) {
16263                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16264                            || ksm[KSM_VOLATILE] != 0) {
16265                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16266                                pw.print(" saved from shared ");
16267                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16268                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16269                                pw.print(" unshared; ");
16270                                pw.print(stringifyKBSize(
16271                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16272                    }
16273                    pw.print("   Tuning: ");
16274                    pw.print(ActivityManager.staticGetMemoryClass());
16275                    pw.print(" (large ");
16276                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16277                    pw.print("), oom ");
16278                    pw.print(stringifySize(
16279                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16280                    pw.print(", restore limit ");
16281                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16282                    if (ActivityManager.isLowRamDeviceStatic()) {
16283                        pw.print(" (low-ram)");
16284                    }
16285                    if (ActivityManager.isHighEndGfx()) {
16286                        pw.print(" (high-end-gfx)");
16287                    }
16288                    pw.println();
16289                } else {
16290                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16291                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16292                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16293                    pw.print("tuning,");
16294                    pw.print(ActivityManager.staticGetMemoryClass());
16295                    pw.print(',');
16296                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16297                    pw.print(',');
16298                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16299                    if (ActivityManager.isLowRamDeviceStatic()) {
16300                        pw.print(",low-ram");
16301                    }
16302                    if (ActivityManager.isHighEndGfx()) {
16303                        pw.print(",high-end-gfx");
16304                    }
16305                    pw.println();
16306                }
16307            }
16308        }
16309    }
16310
16311    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16312            long memtrack, String name) {
16313        sb.append("  ");
16314        sb.append(ProcessList.makeOomAdjString(oomAdj));
16315        sb.append(' ');
16316        sb.append(ProcessList.makeProcStateString(procState));
16317        sb.append(' ');
16318        ProcessList.appendRamKb(sb, pss);
16319        sb.append(": ");
16320        sb.append(name);
16321        if (memtrack > 0) {
16322            sb.append(" (");
16323            sb.append(stringifyKBSize(memtrack));
16324            sb.append(" memtrack)");
16325        }
16326    }
16327
16328    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16329        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16330        sb.append(" (pid ");
16331        sb.append(mi.pid);
16332        sb.append(") ");
16333        sb.append(mi.adjType);
16334        sb.append('\n');
16335        if (mi.adjReason != null) {
16336            sb.append("                      ");
16337            sb.append(mi.adjReason);
16338            sb.append('\n');
16339        }
16340    }
16341
16342    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16343        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16344        for (int i=0, N=memInfos.size(); i<N; i++) {
16345            ProcessMemInfo mi = memInfos.get(i);
16346            infoMap.put(mi.pid, mi);
16347        }
16348        updateCpuStatsNow();
16349        long[] memtrackTmp = new long[1];
16350        final List<ProcessCpuTracker.Stats> stats;
16351        // Get a list of Stats that have vsize > 0
16352        synchronized (mProcessCpuTracker) {
16353            stats = mProcessCpuTracker.getStats((st) -> {
16354                return st.vsize > 0;
16355            });
16356        }
16357        final int statsCount = stats.size();
16358        for (int i = 0; i < statsCount; i++) {
16359            ProcessCpuTracker.Stats st = stats.get(i);
16360            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16361            if (pss > 0) {
16362                if (infoMap.indexOfKey(st.pid) < 0) {
16363                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16364                            ProcessList.NATIVE_ADJ, -1, "native", null);
16365                    mi.pss = pss;
16366                    mi.memtrack = memtrackTmp[0];
16367                    memInfos.add(mi);
16368                }
16369            }
16370        }
16371
16372        long totalPss = 0;
16373        long totalMemtrack = 0;
16374        for (int i=0, N=memInfos.size(); i<N; i++) {
16375            ProcessMemInfo mi = memInfos.get(i);
16376            if (mi.pss == 0) {
16377                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16378                mi.memtrack = memtrackTmp[0];
16379            }
16380            totalPss += mi.pss;
16381            totalMemtrack += mi.memtrack;
16382        }
16383        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16384            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16385                if (lhs.oomAdj != rhs.oomAdj) {
16386                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16387                }
16388                if (lhs.pss != rhs.pss) {
16389                    return lhs.pss < rhs.pss ? 1 : -1;
16390                }
16391                return 0;
16392            }
16393        });
16394
16395        StringBuilder tag = new StringBuilder(128);
16396        StringBuilder stack = new StringBuilder(128);
16397        tag.append("Low on memory -- ");
16398        appendMemBucket(tag, totalPss, "total", false);
16399        appendMemBucket(stack, totalPss, "total", true);
16400
16401        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16402        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16403        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16404
16405        boolean firstLine = true;
16406        int lastOomAdj = Integer.MIN_VALUE;
16407        long extraNativeRam = 0;
16408        long extraNativeMemtrack = 0;
16409        long cachedPss = 0;
16410        for (int i=0, N=memInfos.size(); i<N; i++) {
16411            ProcessMemInfo mi = memInfos.get(i);
16412
16413            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16414                cachedPss += mi.pss;
16415            }
16416
16417            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16418                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16419                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16420                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16421                if (lastOomAdj != mi.oomAdj) {
16422                    lastOomAdj = mi.oomAdj;
16423                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16424                        tag.append(" / ");
16425                    }
16426                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16427                        if (firstLine) {
16428                            stack.append(":");
16429                            firstLine = false;
16430                        }
16431                        stack.append("\n\t at ");
16432                    } else {
16433                        stack.append("$");
16434                    }
16435                } else {
16436                    tag.append(" ");
16437                    stack.append("$");
16438                }
16439                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16440                    appendMemBucket(tag, mi.pss, mi.name, false);
16441                }
16442                appendMemBucket(stack, mi.pss, mi.name, true);
16443                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16444                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16445                    stack.append("(");
16446                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16447                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16448                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16449                            stack.append(":");
16450                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16451                        }
16452                    }
16453                    stack.append(")");
16454                }
16455            }
16456
16457            appendMemInfo(fullNativeBuilder, mi);
16458            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16459                // The short form only has native processes that are >= 512K.
16460                if (mi.pss >= 512) {
16461                    appendMemInfo(shortNativeBuilder, mi);
16462                } else {
16463                    extraNativeRam += mi.pss;
16464                    extraNativeMemtrack += mi.memtrack;
16465                }
16466            } else {
16467                // Short form has all other details, but if we have collected RAM
16468                // from smaller native processes let's dump a summary of that.
16469                if (extraNativeRam > 0) {
16470                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16471                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16472                    shortNativeBuilder.append('\n');
16473                    extraNativeRam = 0;
16474                }
16475                appendMemInfo(fullJavaBuilder, mi);
16476            }
16477        }
16478
16479        fullJavaBuilder.append("           ");
16480        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16481        fullJavaBuilder.append(": TOTAL");
16482        if (totalMemtrack > 0) {
16483            fullJavaBuilder.append(" (");
16484            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16485            fullJavaBuilder.append(" memtrack)");
16486        } else {
16487        }
16488        fullJavaBuilder.append("\n");
16489
16490        MemInfoReader memInfo = new MemInfoReader();
16491        memInfo.readMemInfo();
16492        final long[] infos = memInfo.getRawInfo();
16493
16494        StringBuilder memInfoBuilder = new StringBuilder(1024);
16495        Debug.getMemInfo(infos);
16496        memInfoBuilder.append("  MemInfo: ");
16497        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16498        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16499        memInfoBuilder.append(stringifyKBSize(
16500                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16501        memInfoBuilder.append(stringifyKBSize(
16502                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16503        memInfoBuilder.append(stringifyKBSize(
16504                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16505        memInfoBuilder.append("           ");
16506        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16507        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16508        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16509        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16510        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16511            memInfoBuilder.append("  ZRAM: ");
16512            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16513            memInfoBuilder.append(" RAM, ");
16514            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16515            memInfoBuilder.append(" swap total, ");
16516            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16517            memInfoBuilder.append(" swap free\n");
16518        }
16519        final long[] ksm = getKsmInfo();
16520        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16521                || ksm[KSM_VOLATILE] != 0) {
16522            memInfoBuilder.append("  KSM: ");
16523            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16524            memInfoBuilder.append(" saved from shared ");
16525            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16526            memInfoBuilder.append("\n       ");
16527            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16528            memInfoBuilder.append(" unshared; ");
16529            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16530            memInfoBuilder.append(" volatile\n");
16531        }
16532        memInfoBuilder.append("  Free RAM: ");
16533        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16534                + memInfo.getFreeSizeKb()));
16535        memInfoBuilder.append("\n");
16536        memInfoBuilder.append("  Used RAM: ");
16537        memInfoBuilder.append(stringifyKBSize(
16538                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16539        memInfoBuilder.append("\n");
16540        memInfoBuilder.append("  Lost RAM: ");
16541        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16542                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16543                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16544        memInfoBuilder.append("\n");
16545        Slog.i(TAG, "Low on memory:");
16546        Slog.i(TAG, shortNativeBuilder.toString());
16547        Slog.i(TAG, fullJavaBuilder.toString());
16548        Slog.i(TAG, memInfoBuilder.toString());
16549
16550        StringBuilder dropBuilder = new StringBuilder(1024);
16551        /*
16552        StringWriter oomSw = new StringWriter();
16553        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16554        StringWriter catSw = new StringWriter();
16555        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16556        String[] emptyArgs = new String[] { };
16557        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16558        oomPw.flush();
16559        String oomString = oomSw.toString();
16560        */
16561        dropBuilder.append("Low on memory:");
16562        dropBuilder.append(stack);
16563        dropBuilder.append('\n');
16564        dropBuilder.append(fullNativeBuilder);
16565        dropBuilder.append(fullJavaBuilder);
16566        dropBuilder.append('\n');
16567        dropBuilder.append(memInfoBuilder);
16568        dropBuilder.append('\n');
16569        /*
16570        dropBuilder.append(oomString);
16571        dropBuilder.append('\n');
16572        */
16573        StringWriter catSw = new StringWriter();
16574        synchronized (ActivityManagerService.this) {
16575            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16576            String[] emptyArgs = new String[] { };
16577            catPw.println();
16578            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16579            catPw.println();
16580            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16581                    false, null).dumpLocked();
16582            catPw.println();
16583            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16584            catPw.flush();
16585        }
16586        dropBuilder.append(catSw.toString());
16587        addErrorToDropBox("lowmem", null, "system_server", null,
16588                null, tag.toString(), dropBuilder.toString(), null, null);
16589        //Slog.i(TAG, "Sent to dropbox:");
16590        //Slog.i(TAG, dropBuilder.toString());
16591        synchronized (ActivityManagerService.this) {
16592            long now = SystemClock.uptimeMillis();
16593            if (mLastMemUsageReportTime < now) {
16594                mLastMemUsageReportTime = now;
16595            }
16596        }
16597    }
16598
16599    /**
16600     * Searches array of arguments for the specified string
16601     * @param args array of argument strings
16602     * @param value value to search for
16603     * @return true if the value is contained in the array
16604     */
16605    private static boolean scanArgs(String[] args, String value) {
16606        if (args != null) {
16607            for (String arg : args) {
16608                if (value.equals(arg)) {
16609                    return true;
16610                }
16611            }
16612        }
16613        return false;
16614    }
16615
16616    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16617            ContentProviderRecord cpr, boolean always) {
16618        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16619
16620        if (!inLaunching || always) {
16621            synchronized (cpr) {
16622                cpr.launchingApp = null;
16623                cpr.notifyAll();
16624            }
16625            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16626            String names[] = cpr.info.authority.split(";");
16627            for (int j = 0; j < names.length; j++) {
16628                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16629            }
16630        }
16631
16632        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16633            ContentProviderConnection conn = cpr.connections.get(i);
16634            if (conn.waiting) {
16635                // If this connection is waiting for the provider, then we don't
16636                // need to mess with its process unless we are always removing
16637                // or for some reason the provider is not currently launching.
16638                if (inLaunching && !always) {
16639                    continue;
16640                }
16641            }
16642            ProcessRecord capp = conn.client;
16643            conn.dead = true;
16644            if (conn.stableCount > 0) {
16645                if (!capp.persistent && capp.thread != null
16646                        && capp.pid != 0
16647                        && capp.pid != MY_PID) {
16648                    capp.kill("depends on provider "
16649                            + cpr.name.flattenToShortString()
16650                            + " in dying proc " + (proc != null ? proc.processName : "??")
16651                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16652                }
16653            } else if (capp.thread != null && conn.provider.provider != null) {
16654                try {
16655                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16656                } catch (RemoteException e) {
16657                }
16658                // In the protocol here, we don't expect the client to correctly
16659                // clean up this connection, we'll just remove it.
16660                cpr.connections.remove(i);
16661                if (conn.client.conProviders.remove(conn)) {
16662                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16663                }
16664            }
16665        }
16666
16667        if (inLaunching && always) {
16668            mLaunchingProviders.remove(cpr);
16669        }
16670        return inLaunching;
16671    }
16672
16673    /**
16674     * Main code for cleaning up a process when it has gone away.  This is
16675     * called both as a result of the process dying, or directly when stopping
16676     * a process when running in single process mode.
16677     *
16678     * @return Returns true if the given process has been restarted, so the
16679     * app that was passed in must remain on the process lists.
16680     */
16681    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16682            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16683        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16684        if (index >= 0) {
16685            removeLruProcessLocked(app);
16686            ProcessList.remove(app.pid);
16687        }
16688
16689        mProcessesToGc.remove(app);
16690        mPendingPssProcesses.remove(app);
16691
16692        // Dismiss any open dialogs.
16693        if (app.crashDialog != null && !app.forceCrashReport) {
16694            app.crashDialog.dismiss();
16695            app.crashDialog = null;
16696        }
16697        if (app.anrDialog != null) {
16698            app.anrDialog.dismiss();
16699            app.anrDialog = null;
16700        }
16701        if (app.waitDialog != null) {
16702            app.waitDialog.dismiss();
16703            app.waitDialog = null;
16704        }
16705
16706        app.crashing = false;
16707        app.notResponding = false;
16708
16709        app.resetPackageList(mProcessStats);
16710        app.unlinkDeathRecipient();
16711        app.makeInactive(mProcessStats);
16712        app.waitingToKill = null;
16713        app.forcingToForeground = null;
16714        updateProcessForegroundLocked(app, false, false);
16715        app.foregroundActivities = false;
16716        app.hasShownUi = false;
16717        app.treatLikeActivity = false;
16718        app.hasAboveClient = false;
16719        app.hasClientActivities = false;
16720
16721        mServices.killServicesLocked(app, allowRestart);
16722
16723        boolean restart = false;
16724
16725        // Remove published content providers.
16726        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16727            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16728            final boolean always = app.bad || !allowRestart;
16729            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16730            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16731                // We left the provider in the launching list, need to
16732                // restart it.
16733                restart = true;
16734            }
16735
16736            cpr.provider = null;
16737            cpr.proc = null;
16738        }
16739        app.pubProviders.clear();
16740
16741        // Take care of any launching providers waiting for this process.
16742        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16743            restart = true;
16744        }
16745
16746        // Unregister from connected content providers.
16747        if (!app.conProviders.isEmpty()) {
16748            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16749                ContentProviderConnection conn = app.conProviders.get(i);
16750                conn.provider.connections.remove(conn);
16751                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16752                        conn.provider.name);
16753            }
16754            app.conProviders.clear();
16755        }
16756
16757        // At this point there may be remaining entries in mLaunchingProviders
16758        // where we were the only one waiting, so they are no longer of use.
16759        // Look for these and clean up if found.
16760        // XXX Commented out for now.  Trying to figure out a way to reproduce
16761        // the actual situation to identify what is actually going on.
16762        if (false) {
16763            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16764                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16765                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16766                    synchronized (cpr) {
16767                        cpr.launchingApp = null;
16768                        cpr.notifyAll();
16769                    }
16770                }
16771            }
16772        }
16773
16774        skipCurrentReceiverLocked(app);
16775
16776        // Unregister any receivers.
16777        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16778            removeReceiverLocked(app.receivers.valueAt(i));
16779        }
16780        app.receivers.clear();
16781
16782        // If the app is undergoing backup, tell the backup manager about it
16783        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16784            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16785                    + mBackupTarget.appInfo + " died during backup");
16786            try {
16787                IBackupManager bm = IBackupManager.Stub.asInterface(
16788                        ServiceManager.getService(Context.BACKUP_SERVICE));
16789                bm.agentDisconnected(app.info.packageName);
16790            } catch (RemoteException e) {
16791                // can't happen; backup manager is local
16792            }
16793        }
16794
16795        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16796            ProcessChangeItem item = mPendingProcessChanges.get(i);
16797            if (item.pid == app.pid) {
16798                mPendingProcessChanges.remove(i);
16799                mAvailProcessChanges.add(item);
16800            }
16801        }
16802        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16803                null).sendToTarget();
16804
16805        // If the caller is restarting this app, then leave it in its
16806        // current lists and let the caller take care of it.
16807        if (restarting) {
16808            return false;
16809        }
16810
16811        if (!app.persistent || app.isolated) {
16812            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16813                    "Removing non-persistent process during cleanup: " + app);
16814            if (!replacingPid) {
16815                removeProcessNameLocked(app.processName, app.uid);
16816            }
16817            if (mHeavyWeightProcess == app) {
16818                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16819                        mHeavyWeightProcess.userId, 0));
16820                mHeavyWeightProcess = null;
16821            }
16822        } else if (!app.removed) {
16823            // This app is persistent, so we need to keep its record around.
16824            // If it is not already on the pending app list, add it there
16825            // and start a new process for it.
16826            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16827                mPersistentStartingProcesses.add(app);
16828                restart = true;
16829            }
16830        }
16831        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16832                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16833        mProcessesOnHold.remove(app);
16834
16835        if (app == mHomeProcess) {
16836            mHomeProcess = null;
16837        }
16838        if (app == mPreviousProcess) {
16839            mPreviousProcess = null;
16840        }
16841
16842        if (restart && !app.isolated) {
16843            // We have components that still need to be running in the
16844            // process, so re-launch it.
16845            if (index < 0) {
16846                ProcessList.remove(app.pid);
16847            }
16848            addProcessNameLocked(app);
16849            startProcessLocked(app, "restart", app.processName);
16850            return true;
16851        } else if (app.pid > 0 && app.pid != MY_PID) {
16852            // Goodbye!
16853            boolean removed;
16854            synchronized (mPidsSelfLocked) {
16855                mPidsSelfLocked.remove(app.pid);
16856                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16857            }
16858            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16859            if (app.isolated) {
16860                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16861            }
16862            app.setPid(0);
16863        }
16864        return false;
16865    }
16866
16867    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16868        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16869            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16870            if (cpr.launchingApp == app) {
16871                return true;
16872            }
16873        }
16874        return false;
16875    }
16876
16877    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16878        // Look through the content providers we are waiting to have launched,
16879        // and if any run in this process then either schedule a restart of
16880        // the process or kill the client waiting for it if this process has
16881        // gone bad.
16882        boolean restart = false;
16883        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16884            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16885            if (cpr.launchingApp == app) {
16886                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16887                    restart = true;
16888                } else {
16889                    removeDyingProviderLocked(app, cpr, true);
16890                }
16891            }
16892        }
16893        return restart;
16894    }
16895
16896    // =========================================================
16897    // SERVICES
16898    // =========================================================
16899
16900    @Override
16901    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16902            int flags) {
16903        enforceNotIsolatedCaller("getServices");
16904        synchronized (this) {
16905            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16906        }
16907    }
16908
16909    @Override
16910    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16911        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16912        synchronized (this) {
16913            return mServices.getRunningServiceControlPanelLocked(name);
16914        }
16915    }
16916
16917    @Override
16918    public ComponentName startService(IApplicationThread caller, Intent service,
16919            String resolvedType, String callingPackage, int userId)
16920            throws TransactionTooLargeException {
16921        enforceNotIsolatedCaller("startService");
16922        // Refuse possible leaked file descriptors
16923        if (service != null && service.hasFileDescriptors() == true) {
16924            throw new IllegalArgumentException("File descriptors passed in Intent");
16925        }
16926
16927        if (callingPackage == null) {
16928            throw new IllegalArgumentException("callingPackage cannot be null");
16929        }
16930
16931        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16932                "startService: " + service + " type=" + resolvedType);
16933        synchronized(this) {
16934            final int callingPid = Binder.getCallingPid();
16935            final int callingUid = Binder.getCallingUid();
16936            final long origId = Binder.clearCallingIdentity();
16937            ComponentName res = mServices.startServiceLocked(caller, service,
16938                    resolvedType, callingPid, callingUid, callingPackage, userId);
16939            Binder.restoreCallingIdentity(origId);
16940            return res;
16941        }
16942    }
16943
16944    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16945            String callingPackage, int userId)
16946            throws TransactionTooLargeException {
16947        synchronized(this) {
16948            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16949                    "startServiceInPackage: " + service + " type=" + resolvedType);
16950            final long origId = Binder.clearCallingIdentity();
16951            ComponentName res = mServices.startServiceLocked(null, service,
16952                    resolvedType, -1, uid, callingPackage, userId);
16953            Binder.restoreCallingIdentity(origId);
16954            return res;
16955        }
16956    }
16957
16958    @Override
16959    public int stopService(IApplicationThread caller, Intent service,
16960            String resolvedType, int userId) {
16961        enforceNotIsolatedCaller("stopService");
16962        // Refuse possible leaked file descriptors
16963        if (service != null && service.hasFileDescriptors() == true) {
16964            throw new IllegalArgumentException("File descriptors passed in Intent");
16965        }
16966
16967        synchronized(this) {
16968            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16969        }
16970    }
16971
16972    @Override
16973    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16974        enforceNotIsolatedCaller("peekService");
16975        // Refuse possible leaked file descriptors
16976        if (service != null && service.hasFileDescriptors() == true) {
16977            throw new IllegalArgumentException("File descriptors passed in Intent");
16978        }
16979
16980        if (callingPackage == null) {
16981            throw new IllegalArgumentException("callingPackage cannot be null");
16982        }
16983
16984        synchronized(this) {
16985            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16986        }
16987    }
16988
16989    @Override
16990    public boolean stopServiceToken(ComponentName className, IBinder token,
16991            int startId) {
16992        synchronized(this) {
16993            return mServices.stopServiceTokenLocked(className, token, startId);
16994        }
16995    }
16996
16997    @Override
16998    public void setServiceForeground(ComponentName className, IBinder token,
16999            int id, Notification notification, int flags) {
17000        synchronized(this) {
17001            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17002        }
17003    }
17004
17005    @Override
17006    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17007            boolean requireFull, String name, String callerPackage) {
17008        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17009                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17010    }
17011
17012    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17013            String className, int flags) {
17014        boolean result = false;
17015        // For apps that don't have pre-defined UIDs, check for permission
17016        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17017            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17018                if (ActivityManager.checkUidPermission(
17019                        INTERACT_ACROSS_USERS,
17020                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17021                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17022                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17023                            + " requests FLAG_SINGLE_USER, but app does not hold "
17024                            + INTERACT_ACROSS_USERS;
17025                    Slog.w(TAG, msg);
17026                    throw new SecurityException(msg);
17027                }
17028                // Permission passed
17029                result = true;
17030            }
17031        } else if ("system".equals(componentProcessName)) {
17032            result = true;
17033        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17034            // Phone app and persistent apps are allowed to export singleuser providers.
17035            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17036                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17037        }
17038        if (DEBUG_MU) Slog.v(TAG_MU,
17039                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17040                + Integer.toHexString(flags) + ") = " + result);
17041        return result;
17042    }
17043
17044    /**
17045     * Checks to see if the caller is in the same app as the singleton
17046     * component, or the component is in a special app. It allows special apps
17047     * to export singleton components but prevents exporting singleton
17048     * components for regular apps.
17049     */
17050    boolean isValidSingletonCall(int callingUid, int componentUid) {
17051        int componentAppId = UserHandle.getAppId(componentUid);
17052        return UserHandle.isSameApp(callingUid, componentUid)
17053                || componentAppId == Process.SYSTEM_UID
17054                || componentAppId == Process.PHONE_UID
17055                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17056                        == PackageManager.PERMISSION_GRANTED;
17057    }
17058
17059    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17060            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17061            int userId) throws TransactionTooLargeException {
17062        enforceNotIsolatedCaller("bindService");
17063
17064        // Refuse possible leaked file descriptors
17065        if (service != null && service.hasFileDescriptors() == true) {
17066            throw new IllegalArgumentException("File descriptors passed in Intent");
17067        }
17068
17069        if (callingPackage == null) {
17070            throw new IllegalArgumentException("callingPackage cannot be null");
17071        }
17072
17073        synchronized(this) {
17074            return mServices.bindServiceLocked(caller, token, service,
17075                    resolvedType, connection, flags, callingPackage, userId);
17076        }
17077    }
17078
17079    public boolean unbindService(IServiceConnection connection) {
17080        synchronized (this) {
17081            return mServices.unbindServiceLocked(connection);
17082        }
17083    }
17084
17085    public void publishService(IBinder token, Intent intent, IBinder service) {
17086        // Refuse possible leaked file descriptors
17087        if (intent != null && intent.hasFileDescriptors() == true) {
17088            throw new IllegalArgumentException("File descriptors passed in Intent");
17089        }
17090
17091        synchronized(this) {
17092            if (!(token instanceof ServiceRecord)) {
17093                throw new IllegalArgumentException("Invalid service token");
17094            }
17095            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17096        }
17097    }
17098
17099    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17100        // Refuse possible leaked file descriptors
17101        if (intent != null && intent.hasFileDescriptors() == true) {
17102            throw new IllegalArgumentException("File descriptors passed in Intent");
17103        }
17104
17105        synchronized(this) {
17106            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17107        }
17108    }
17109
17110    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17111        synchronized(this) {
17112            if (!(token instanceof ServiceRecord)) {
17113                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17114                throw new IllegalArgumentException("Invalid service token");
17115            }
17116            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17117        }
17118    }
17119
17120    // =========================================================
17121    // BACKUP AND RESTORE
17122    // =========================================================
17123
17124    // Cause the target app to be launched if necessary and its backup agent
17125    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17126    // activity manager to announce its creation.
17127    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17128        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17129        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17130
17131        IPackageManager pm = AppGlobals.getPackageManager();
17132        ApplicationInfo app = null;
17133        try {
17134            app = pm.getApplicationInfo(packageName, 0, userId);
17135        } catch (RemoteException e) {
17136            // can't happen; package manager is process-local
17137        }
17138        if (app == null) {
17139            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17140            return false;
17141        }
17142
17143        synchronized(this) {
17144            // !!! TODO: currently no check here that we're already bound
17145            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17146            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17147            synchronized (stats) {
17148                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17149            }
17150
17151            // Backup agent is now in use, its package can't be stopped.
17152            try {
17153                AppGlobals.getPackageManager().setPackageStoppedState(
17154                        app.packageName, false, UserHandle.getUserId(app.uid));
17155            } catch (RemoteException e) {
17156            } catch (IllegalArgumentException e) {
17157                Slog.w(TAG, "Failed trying to unstop package "
17158                        + app.packageName + ": " + e);
17159            }
17160
17161            BackupRecord r = new BackupRecord(ss, app, backupMode);
17162            ComponentName hostingName =
17163                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17164                            ? new ComponentName(app.packageName, app.backupAgentName)
17165                            : new ComponentName("android", "FullBackupAgent");
17166            // startProcessLocked() returns existing proc's record if it's already running
17167            ProcessRecord proc = startProcessLocked(app.processName, app,
17168                    false, 0, "backup", hostingName, false, false, false);
17169            if (proc == null) {
17170                Slog.e(TAG, "Unable to start backup agent process " + r);
17171                return false;
17172            }
17173
17174            // If the app is a regular app (uid >= 10000) and not the system server or phone
17175            // process, etc, then mark it as being in full backup so that certain calls to the
17176            // process can be blocked. This is not reset to false anywhere because we kill the
17177            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17178            if (UserHandle.isApp(app.uid) &&
17179                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17180                proc.inFullBackup = true;
17181            }
17182            r.app = proc;
17183            mBackupTarget = r;
17184            mBackupAppName = app.packageName;
17185
17186            // Try not to kill the process during backup
17187            updateOomAdjLocked(proc);
17188
17189            // If the process is already attached, schedule the creation of the backup agent now.
17190            // If it is not yet live, this will be done when it attaches to the framework.
17191            if (proc.thread != null) {
17192                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17193                try {
17194                    proc.thread.scheduleCreateBackupAgent(app,
17195                            compatibilityInfoForPackageLocked(app), backupMode);
17196                } catch (RemoteException e) {
17197                    // Will time out on the backup manager side
17198                }
17199            } else {
17200                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17201            }
17202            // Invariants: at this point, the target app process exists and the application
17203            // is either already running or in the process of coming up.  mBackupTarget and
17204            // mBackupAppName describe the app, so that when it binds back to the AM we
17205            // know that it's scheduled for a backup-agent operation.
17206        }
17207
17208        return true;
17209    }
17210
17211    @Override
17212    public void clearPendingBackup() {
17213        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17214        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17215
17216        synchronized (this) {
17217            mBackupTarget = null;
17218            mBackupAppName = null;
17219        }
17220    }
17221
17222    // A backup agent has just come up
17223    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17224        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17225                + " = " + agent);
17226
17227        synchronized(this) {
17228            if (!agentPackageName.equals(mBackupAppName)) {
17229                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17230                return;
17231            }
17232        }
17233
17234        long oldIdent = Binder.clearCallingIdentity();
17235        try {
17236            IBackupManager bm = IBackupManager.Stub.asInterface(
17237                    ServiceManager.getService(Context.BACKUP_SERVICE));
17238            bm.agentConnected(agentPackageName, agent);
17239        } catch (RemoteException e) {
17240            // can't happen; the backup manager service is local
17241        } catch (Exception e) {
17242            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17243            e.printStackTrace();
17244        } finally {
17245            Binder.restoreCallingIdentity(oldIdent);
17246        }
17247    }
17248
17249    // done with this agent
17250    public void unbindBackupAgent(ApplicationInfo appInfo) {
17251        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17252        if (appInfo == null) {
17253            Slog.w(TAG, "unbind backup agent for null app");
17254            return;
17255        }
17256
17257        synchronized(this) {
17258            try {
17259                if (mBackupAppName == null) {
17260                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17261                    return;
17262                }
17263
17264                if (!mBackupAppName.equals(appInfo.packageName)) {
17265                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17266                    return;
17267                }
17268
17269                // Not backing this app up any more; reset its OOM adjustment
17270                final ProcessRecord proc = mBackupTarget.app;
17271                updateOomAdjLocked(proc);
17272
17273                // If the app crashed during backup, 'thread' will be null here
17274                if (proc.thread != null) {
17275                    try {
17276                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17277                                compatibilityInfoForPackageLocked(appInfo));
17278                    } catch (Exception e) {
17279                        Slog.e(TAG, "Exception when unbinding backup agent:");
17280                        e.printStackTrace();
17281                    }
17282                }
17283            } finally {
17284                mBackupTarget = null;
17285                mBackupAppName = null;
17286            }
17287        }
17288    }
17289    // =========================================================
17290    // BROADCASTS
17291    // =========================================================
17292
17293    boolean isPendingBroadcastProcessLocked(int pid) {
17294        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17295                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17296    }
17297
17298    void skipPendingBroadcastLocked(int pid) {
17299            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17300            for (BroadcastQueue queue : mBroadcastQueues) {
17301                queue.skipPendingBroadcastLocked(pid);
17302            }
17303    }
17304
17305    // The app just attached; send any pending broadcasts that it should receive
17306    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17307        boolean didSomething = false;
17308        for (BroadcastQueue queue : mBroadcastQueues) {
17309            didSomething |= queue.sendPendingBroadcastsLocked(app);
17310        }
17311        return didSomething;
17312    }
17313
17314    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17315            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17316        enforceNotIsolatedCaller("registerReceiver");
17317        ArrayList<Intent> stickyIntents = null;
17318        ProcessRecord callerApp = null;
17319        int callingUid;
17320        int callingPid;
17321        synchronized(this) {
17322            if (caller != null) {
17323                callerApp = getRecordForAppLocked(caller);
17324                if (callerApp == null) {
17325                    throw new SecurityException(
17326                            "Unable to find app for caller " + caller
17327                            + " (pid=" + Binder.getCallingPid()
17328                            + ") when registering receiver " + receiver);
17329                }
17330                if (callerApp.info.uid != Process.SYSTEM_UID &&
17331                        !callerApp.pkgList.containsKey(callerPackage) &&
17332                        !"android".equals(callerPackage)) {
17333                    throw new SecurityException("Given caller package " + callerPackage
17334                            + " is not running in process " + callerApp);
17335                }
17336                callingUid = callerApp.info.uid;
17337                callingPid = callerApp.pid;
17338            } else {
17339                callerPackage = null;
17340                callingUid = Binder.getCallingUid();
17341                callingPid = Binder.getCallingPid();
17342            }
17343
17344            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17345                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17346
17347            Iterator<String> actions = filter.actionsIterator();
17348            if (actions == null) {
17349                ArrayList<String> noAction = new ArrayList<String>(1);
17350                noAction.add(null);
17351                actions = noAction.iterator();
17352            }
17353
17354            // Collect stickies of users
17355            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17356            while (actions.hasNext()) {
17357                String action = actions.next();
17358                for (int id : userIds) {
17359                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17360                    if (stickies != null) {
17361                        ArrayList<Intent> intents = stickies.get(action);
17362                        if (intents != null) {
17363                            if (stickyIntents == null) {
17364                                stickyIntents = new ArrayList<Intent>();
17365                            }
17366                            stickyIntents.addAll(intents);
17367                        }
17368                    }
17369                }
17370            }
17371        }
17372
17373        ArrayList<Intent> allSticky = null;
17374        if (stickyIntents != null) {
17375            final ContentResolver resolver = mContext.getContentResolver();
17376            // Look for any matching sticky broadcasts...
17377            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17378                Intent intent = stickyIntents.get(i);
17379                // If intent has scheme "content", it will need to acccess
17380                // provider that needs to lock mProviderMap in ActivityThread
17381                // and also it may need to wait application response, so we
17382                // cannot lock ActivityManagerService here.
17383                if (filter.match(resolver, intent, true, TAG) >= 0) {
17384                    if (allSticky == null) {
17385                        allSticky = new ArrayList<Intent>();
17386                    }
17387                    allSticky.add(intent);
17388                }
17389            }
17390        }
17391
17392        // The first sticky in the list is returned directly back to the client.
17393        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17394        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17395        if (receiver == null) {
17396            return sticky;
17397        }
17398
17399        synchronized (this) {
17400            if (callerApp != null && (callerApp.thread == null
17401                    || callerApp.thread.asBinder() != caller.asBinder())) {
17402                // Original caller already died
17403                return null;
17404            }
17405            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17406            if (rl == null) {
17407                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17408                        userId, receiver);
17409                if (rl.app != null) {
17410                    rl.app.receivers.add(rl);
17411                } else {
17412                    try {
17413                        receiver.asBinder().linkToDeath(rl, 0);
17414                    } catch (RemoteException e) {
17415                        return sticky;
17416                    }
17417                    rl.linkedToDeath = true;
17418                }
17419                mRegisteredReceivers.put(receiver.asBinder(), rl);
17420            } else if (rl.uid != callingUid) {
17421                throw new IllegalArgumentException(
17422                        "Receiver requested to register for uid " + callingUid
17423                        + " was previously registered for uid " + rl.uid);
17424            } else if (rl.pid != callingPid) {
17425                throw new IllegalArgumentException(
17426                        "Receiver requested to register for pid " + callingPid
17427                        + " was previously registered for pid " + rl.pid);
17428            } else if (rl.userId != userId) {
17429                throw new IllegalArgumentException(
17430                        "Receiver requested to register for user " + userId
17431                        + " was previously registered for user " + rl.userId);
17432            }
17433            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17434                    permission, callingUid, userId);
17435            rl.add(bf);
17436            if (!bf.debugCheck()) {
17437                Slog.w(TAG, "==> For Dynamic broadcast");
17438            }
17439            mReceiverResolver.addFilter(bf);
17440
17441            // Enqueue broadcasts for all existing stickies that match
17442            // this filter.
17443            if (allSticky != null) {
17444                ArrayList receivers = new ArrayList();
17445                receivers.add(bf);
17446
17447                final int stickyCount = allSticky.size();
17448                for (int i = 0; i < stickyCount; i++) {
17449                    Intent intent = allSticky.get(i);
17450                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17451                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17452                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17453                            null, 0, null, null, false, true, true, -1);
17454                    queue.enqueueParallelBroadcastLocked(r);
17455                    queue.scheduleBroadcastsLocked();
17456                }
17457            }
17458
17459            return sticky;
17460        }
17461    }
17462
17463    public void unregisterReceiver(IIntentReceiver receiver) {
17464        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17465
17466        final long origId = Binder.clearCallingIdentity();
17467        try {
17468            boolean doTrim = false;
17469
17470            synchronized(this) {
17471                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17472                if (rl != null) {
17473                    final BroadcastRecord r = rl.curBroadcast;
17474                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17475                        final boolean doNext = r.queue.finishReceiverLocked(
17476                                r, r.resultCode, r.resultData, r.resultExtras,
17477                                r.resultAbort, false);
17478                        if (doNext) {
17479                            doTrim = true;
17480                            r.queue.processNextBroadcast(false);
17481                        }
17482                    }
17483
17484                    if (rl.app != null) {
17485                        rl.app.receivers.remove(rl);
17486                    }
17487                    removeReceiverLocked(rl);
17488                    if (rl.linkedToDeath) {
17489                        rl.linkedToDeath = false;
17490                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17491                    }
17492                }
17493            }
17494
17495            // If we actually concluded any broadcasts, we might now be able
17496            // to trim the recipients' apps from our working set
17497            if (doTrim) {
17498                trimApplications();
17499                return;
17500            }
17501
17502        } finally {
17503            Binder.restoreCallingIdentity(origId);
17504        }
17505    }
17506
17507    void removeReceiverLocked(ReceiverList rl) {
17508        mRegisteredReceivers.remove(rl.receiver.asBinder());
17509        for (int i = rl.size() - 1; i >= 0; i--) {
17510            mReceiverResolver.removeFilter(rl.get(i));
17511        }
17512    }
17513
17514    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17515        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17516            ProcessRecord r = mLruProcesses.get(i);
17517            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17518                try {
17519                    r.thread.dispatchPackageBroadcast(cmd, packages);
17520                } catch (RemoteException ex) {
17521                }
17522            }
17523        }
17524    }
17525
17526    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17527            int callingUid, int[] users) {
17528        // TODO: come back and remove this assumption to triage all broadcasts
17529        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17530
17531        List<ResolveInfo> receivers = null;
17532        try {
17533            HashSet<ComponentName> singleUserReceivers = null;
17534            boolean scannedFirstReceivers = false;
17535            for (int user : users) {
17536                // Skip users that have Shell restrictions, with exception of always permitted
17537                // Shell broadcasts
17538                if (callingUid == Process.SHELL_UID
17539                        && mUserController.hasUserRestriction(
17540                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17541                        && !isPermittedShellBroadcast(intent)) {
17542                    continue;
17543                }
17544                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17545                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17546                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17547                    // If this is not the system user, we need to check for
17548                    // any receivers that should be filtered out.
17549                    for (int i=0; i<newReceivers.size(); i++) {
17550                        ResolveInfo ri = newReceivers.get(i);
17551                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17552                            newReceivers.remove(i);
17553                            i--;
17554                        }
17555                    }
17556                }
17557                if (newReceivers != null && newReceivers.size() == 0) {
17558                    newReceivers = null;
17559                }
17560                if (receivers == null) {
17561                    receivers = newReceivers;
17562                } else if (newReceivers != null) {
17563                    // We need to concatenate the additional receivers
17564                    // found with what we have do far.  This would be easy,
17565                    // but we also need to de-dup any receivers that are
17566                    // singleUser.
17567                    if (!scannedFirstReceivers) {
17568                        // Collect any single user receivers we had already retrieved.
17569                        scannedFirstReceivers = true;
17570                        for (int i=0; i<receivers.size(); i++) {
17571                            ResolveInfo ri = receivers.get(i);
17572                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17573                                ComponentName cn = new ComponentName(
17574                                        ri.activityInfo.packageName, ri.activityInfo.name);
17575                                if (singleUserReceivers == null) {
17576                                    singleUserReceivers = new HashSet<ComponentName>();
17577                                }
17578                                singleUserReceivers.add(cn);
17579                            }
17580                        }
17581                    }
17582                    // Add the new results to the existing results, tracking
17583                    // and de-dupping single user receivers.
17584                    for (int i=0; i<newReceivers.size(); i++) {
17585                        ResolveInfo ri = newReceivers.get(i);
17586                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17587                            ComponentName cn = new ComponentName(
17588                                    ri.activityInfo.packageName, ri.activityInfo.name);
17589                            if (singleUserReceivers == null) {
17590                                singleUserReceivers = new HashSet<ComponentName>();
17591                            }
17592                            if (!singleUserReceivers.contains(cn)) {
17593                                singleUserReceivers.add(cn);
17594                                receivers.add(ri);
17595                            }
17596                        } else {
17597                            receivers.add(ri);
17598                        }
17599                    }
17600                }
17601            }
17602        } catch (RemoteException ex) {
17603            // pm is in same process, this will never happen.
17604        }
17605        return receivers;
17606    }
17607
17608    private boolean isPermittedShellBroadcast(Intent intent) {
17609        // remote bugreport should always be allowed to be taken
17610        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17611    }
17612
17613    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17614            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17615        final String action = intent.getAction();
17616        if (isProtectedBroadcast
17617                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17618                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17619                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17620                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17621                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17622                || Intent.ACTION_MASTER_CLEAR.equals(action)
17623                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17624                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17625                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17626                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17627                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17628            // Broadcast is either protected, or it's a public action that
17629            // we've relaxed, so it's fine for system internals to send.
17630            return;
17631        }
17632
17633        // This broadcast may be a problem...  but there are often system components that
17634        // want to send an internal broadcast to themselves, which is annoying to have to
17635        // explicitly list each action as a protected broadcast, so we will check for that
17636        // one safe case and allow it: an explicit broadcast, only being received by something
17637        // that has protected itself.
17638        if (receivers != null && receivers.size() > 0
17639                && (intent.getPackage() != null || intent.getComponent() != null)) {
17640            boolean allProtected = true;
17641            for (int i = receivers.size()-1; i >= 0; i--) {
17642                Object target = receivers.get(i);
17643                if (target instanceof ResolveInfo) {
17644                    ResolveInfo ri = (ResolveInfo)target;
17645                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17646                        allProtected = false;
17647                        break;
17648                    }
17649                } else {
17650                    BroadcastFilter bf = (BroadcastFilter)target;
17651                    if (bf.requiredPermission == null) {
17652                        allProtected = false;
17653                        break;
17654                    }
17655                }
17656            }
17657            if (allProtected) {
17658                // All safe!
17659                return;
17660            }
17661        }
17662
17663        // The vast majority of broadcasts sent from system internals
17664        // should be protected to avoid security holes, so yell loudly
17665        // to ensure we examine these cases.
17666        if (callerApp != null) {
17667            Log.wtf(TAG, "Sending non-protected broadcast " + action
17668                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17669                    new Throwable());
17670        } else {
17671            Log.wtf(TAG, "Sending non-protected broadcast " + action
17672                            + " from system uid " + UserHandle.formatUid(callingUid)
17673                            + " pkg " + callerPackage,
17674                    new Throwable());
17675        }
17676    }
17677
17678    final int broadcastIntentLocked(ProcessRecord callerApp,
17679            String callerPackage, Intent intent, String resolvedType,
17680            IIntentReceiver resultTo, int resultCode, String resultData,
17681            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17682            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17683        intent = new Intent(intent);
17684
17685        // By default broadcasts do not go to stopped apps.
17686        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17687
17688        // If we have not finished booting, don't allow this to launch new processes.
17689        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17690            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17691        }
17692
17693        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17694                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17695                + " ordered=" + ordered + " userid=" + userId);
17696        if ((resultTo != null) && !ordered) {
17697            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17698        }
17699
17700        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17701                ALLOW_NON_FULL, "broadcast", callerPackage);
17702
17703        // Make sure that the user who is receiving this broadcast is running.
17704        // If not, we will just skip it. Make an exception for shutdown broadcasts
17705        // and upgrade steps.
17706
17707        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17708            if ((callingUid != Process.SYSTEM_UID
17709                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17710                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17711                Slog.w(TAG, "Skipping broadcast of " + intent
17712                        + ": user " + userId + " is stopped");
17713                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17714            }
17715        }
17716
17717        BroadcastOptions brOptions = null;
17718        if (bOptions != null) {
17719            brOptions = new BroadcastOptions(bOptions);
17720            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17721                // See if the caller is allowed to do this.  Note we are checking against
17722                // the actual real caller (not whoever provided the operation as say a
17723                // PendingIntent), because that who is actually supplied the arguments.
17724                if (checkComponentPermission(
17725                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17726                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17727                        != PackageManager.PERMISSION_GRANTED) {
17728                    String msg = "Permission Denial: " + intent.getAction()
17729                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17730                            + ", uid=" + callingUid + ")"
17731                            + " requires "
17732                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17733                    Slog.w(TAG, msg);
17734                    throw new SecurityException(msg);
17735                }
17736            }
17737        }
17738
17739        // Verify that protected broadcasts are only being sent by system code,
17740        // and that system code is only sending protected broadcasts.
17741        final String action = intent.getAction();
17742        final boolean isProtectedBroadcast;
17743        try {
17744            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17745        } catch (RemoteException e) {
17746            Slog.w(TAG, "Remote exception", e);
17747            return ActivityManager.BROADCAST_SUCCESS;
17748        }
17749
17750        final boolean isCallerSystem;
17751        switch (UserHandle.getAppId(callingUid)) {
17752            case Process.ROOT_UID:
17753            case Process.SYSTEM_UID:
17754            case Process.PHONE_UID:
17755            case Process.BLUETOOTH_UID:
17756            case Process.NFC_UID:
17757                isCallerSystem = true;
17758                break;
17759            default:
17760                isCallerSystem = (callerApp != null) && callerApp.persistent;
17761                break;
17762        }
17763
17764        // First line security check before anything else: stop non-system apps from
17765        // sending protected broadcasts.
17766        if (!isCallerSystem) {
17767            if (isProtectedBroadcast) {
17768                String msg = "Permission Denial: not allowed to send broadcast "
17769                        + action + " from pid="
17770                        + callingPid + ", uid=" + callingUid;
17771                Slog.w(TAG, msg);
17772                throw new SecurityException(msg);
17773
17774            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17775                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17776                // Special case for compatibility: we don't want apps to send this,
17777                // but historically it has not been protected and apps may be using it
17778                // to poke their own app widget.  So, instead of making it protected,
17779                // just limit it to the caller.
17780                if (callerPackage == null) {
17781                    String msg = "Permission Denial: not allowed to send broadcast "
17782                            + action + " from unknown caller.";
17783                    Slog.w(TAG, msg);
17784                    throw new SecurityException(msg);
17785                } else if (intent.getComponent() != null) {
17786                    // They are good enough to send to an explicit component...  verify
17787                    // it is being sent to the calling app.
17788                    if (!intent.getComponent().getPackageName().equals(
17789                            callerPackage)) {
17790                        String msg = "Permission Denial: not allowed to send broadcast "
17791                                + action + " to "
17792                                + intent.getComponent().getPackageName() + " from "
17793                                + callerPackage;
17794                        Slog.w(TAG, msg);
17795                        throw new SecurityException(msg);
17796                    }
17797                } else {
17798                    // Limit broadcast to their own package.
17799                    intent.setPackage(callerPackage);
17800                }
17801            }
17802        }
17803
17804        if (action != null) {
17805            switch (action) {
17806                case Intent.ACTION_UID_REMOVED:
17807                case Intent.ACTION_PACKAGE_REMOVED:
17808                case Intent.ACTION_PACKAGE_CHANGED:
17809                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17810                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17811                case Intent.ACTION_PACKAGES_SUSPENDED:
17812                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17813                    // Handle special intents: if this broadcast is from the package
17814                    // manager about a package being removed, we need to remove all of
17815                    // its activities from the history stack.
17816                    if (checkComponentPermission(
17817                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17818                            callingPid, callingUid, -1, true)
17819                            != PackageManager.PERMISSION_GRANTED) {
17820                        String msg = "Permission Denial: " + intent.getAction()
17821                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17822                                + ", uid=" + callingUid + ")"
17823                                + " requires "
17824                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17825                        Slog.w(TAG, msg);
17826                        throw new SecurityException(msg);
17827                    }
17828                    switch (action) {
17829                        case Intent.ACTION_UID_REMOVED:
17830                            final Bundle intentExtras = intent.getExtras();
17831                            final int uid = intentExtras != null
17832                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17833                            if (uid >= 0) {
17834                                mBatteryStatsService.removeUid(uid);
17835                                mAppOpsService.uidRemoved(uid);
17836                            }
17837                            break;
17838                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17839                            // If resources are unavailable just force stop all those packages
17840                            // and flush the attribute cache as well.
17841                            String list[] =
17842                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17843                            if (list != null && list.length > 0) {
17844                                for (int i = 0; i < list.length; i++) {
17845                                    forceStopPackageLocked(list[i], -1, false, true, true,
17846                                            false, false, userId, "storage unmount");
17847                                }
17848                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17849                                sendPackageBroadcastLocked(
17850                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
17851                                        list, userId);
17852                            }
17853                            break;
17854                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17855                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17856                            break;
17857                        case Intent.ACTION_PACKAGE_REMOVED:
17858                        case Intent.ACTION_PACKAGE_CHANGED:
17859                            Uri data = intent.getData();
17860                            String ssp;
17861                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17862                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17863                                final boolean replacing =
17864                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17865                                final boolean killProcess =
17866                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17867                                final boolean fullUninstall = removed && !replacing;
17868                                if (removed) {
17869                                    if (killProcess) {
17870                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17871                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17872                                                false, true, true, false, fullUninstall, userId,
17873                                                removed ? "pkg removed" : "pkg changed");
17874                                    }
17875                                    final int cmd = killProcess
17876                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
17877                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
17878                                    sendPackageBroadcastLocked(cmd,
17879                                            new String[] {ssp}, userId);
17880                                    if (fullUninstall) {
17881                                        mAppOpsService.packageRemoved(
17882                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17883
17884                                        // Remove all permissions granted from/to this package
17885                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17886
17887                                        removeTasksByPackageNameLocked(ssp, userId);
17888
17889                                        // Hide the "unsupported display" dialog if necessary.
17890                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17891                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17892                                            mUnsupportedDisplaySizeDialog.dismiss();
17893                                            mUnsupportedDisplaySizeDialog = null;
17894                                        }
17895                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17896                                        mBatteryStatsService.notePackageUninstalled(ssp);
17897                                    }
17898                                } else {
17899                                    if (killProcess) {
17900                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17901                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17902                                                userId, ProcessList.INVALID_ADJ,
17903                                                false, true, true, false, "change " + ssp);
17904                                    }
17905                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17906                                            intent.getStringArrayExtra(
17907                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17908                                }
17909                            }
17910                            break;
17911                        case Intent.ACTION_PACKAGES_SUSPENDED:
17912                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17913                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17914                                    intent.getAction());
17915                            final String[] packageNames = intent.getStringArrayExtra(
17916                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17917                            final int userHandle = intent.getIntExtra(
17918                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17919
17920                            synchronized(ActivityManagerService.this) {
17921                                mRecentTasks.onPackagesSuspendedChanged(
17922                                        packageNames, suspended, userHandle);
17923                            }
17924                            break;
17925                    }
17926                    break;
17927                case Intent.ACTION_PACKAGE_REPLACED:
17928                {
17929                    final Uri data = intent.getData();
17930                    final String ssp;
17931                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17932                        final ApplicationInfo aInfo =
17933                                getPackageManagerInternalLocked().getApplicationInfo(
17934                                        ssp,
17935                                        userId);
17936                        if (aInfo == null) {
17937                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17938                                    + " ssp=" + ssp + " data=" + data);
17939                            return ActivityManager.BROADCAST_SUCCESS;
17940                        }
17941                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17942                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
17943                                new String[] {ssp}, userId);
17944                    }
17945                    break;
17946                }
17947                case Intent.ACTION_PACKAGE_ADDED:
17948                {
17949                    // Special case for adding a package: by default turn on compatibility mode.
17950                    Uri data = intent.getData();
17951                    String ssp;
17952                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17953                        final boolean replacing =
17954                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17955                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17956
17957                        try {
17958                            ApplicationInfo ai = AppGlobals.getPackageManager().
17959                                    getApplicationInfo(ssp, 0, 0);
17960                            mBatteryStatsService.notePackageInstalled(ssp,
17961                                    ai != null ? ai.versionCode : 0);
17962                        } catch (RemoteException e) {
17963                        }
17964                    }
17965                    break;
17966                }
17967                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17968                {
17969                    Uri data = intent.getData();
17970                    String ssp;
17971                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17972                        // Hide the "unsupported display" dialog if necessary.
17973                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17974                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17975                            mUnsupportedDisplaySizeDialog.dismiss();
17976                            mUnsupportedDisplaySizeDialog = null;
17977                        }
17978                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17979                    }
17980                    break;
17981                }
17982                case Intent.ACTION_TIMEZONE_CHANGED:
17983                    // If this is the time zone changed action, queue up a message that will reset
17984                    // the timezone of all currently running processes. This message will get
17985                    // queued up before the broadcast happens.
17986                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17987                    break;
17988                case Intent.ACTION_TIME_CHANGED:
17989                    // If the user set the time, let all running processes know.
17990                    final int is24Hour =
17991                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17992                                    : 0;
17993                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17994                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17995                    synchronized (stats) {
17996                        stats.noteCurrentTimeChangedLocked();
17997                    }
17998                    break;
17999                case Intent.ACTION_CLEAR_DNS_CACHE:
18000                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18001                    break;
18002                case Proxy.PROXY_CHANGE_ACTION:
18003                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18004                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18005                    break;
18006                case android.hardware.Camera.ACTION_NEW_PICTURE:
18007                case android.hardware.Camera.ACTION_NEW_VIDEO:
18008                    // These broadcasts are no longer allowed by the system, since they can
18009                    // cause significant thrashing at a crictical point (using the camera).
18010                    // Apps should use JobScehduler to monitor for media provider changes.
18011                    Slog.w(TAG, action + " no longer allowed; dropping from "
18012                            + UserHandle.formatUid(callingUid));
18013                    if (resultTo != null) {
18014                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18015                        try {
18016                            queue.performReceiveLocked(callerApp, resultTo, intent,
18017                                    Activity.RESULT_CANCELED, null, null,
18018                                    false, false, userId);
18019                        } catch (RemoteException e) {
18020                            Slog.w(TAG, "Failure ["
18021                                    + queue.mQueueName + "] sending broadcast result of "
18022                                    + intent, e);
18023
18024                        }
18025                    }
18026                    // Lie; we don't want to crash the app.
18027                    return ActivityManager.BROADCAST_SUCCESS;
18028                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18029                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18030                    break;
18031            }
18032        }
18033
18034        // Add to the sticky list if requested.
18035        if (sticky) {
18036            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18037                    callingPid, callingUid)
18038                    != PackageManager.PERMISSION_GRANTED) {
18039                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18040                        + callingPid + ", uid=" + callingUid
18041                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18042                Slog.w(TAG, msg);
18043                throw new SecurityException(msg);
18044            }
18045            if (requiredPermissions != null && requiredPermissions.length > 0) {
18046                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18047                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18048                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18049            }
18050            if (intent.getComponent() != null) {
18051                throw new SecurityException(
18052                        "Sticky broadcasts can't target a specific component");
18053            }
18054            // We use userId directly here, since the "all" target is maintained
18055            // as a separate set of sticky broadcasts.
18056            if (userId != UserHandle.USER_ALL) {
18057                // But first, if this is not a broadcast to all users, then
18058                // make sure it doesn't conflict with an existing broadcast to
18059                // all users.
18060                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18061                        UserHandle.USER_ALL);
18062                if (stickies != null) {
18063                    ArrayList<Intent> list = stickies.get(intent.getAction());
18064                    if (list != null) {
18065                        int N = list.size();
18066                        int i;
18067                        for (i=0; i<N; i++) {
18068                            if (intent.filterEquals(list.get(i))) {
18069                                throw new IllegalArgumentException(
18070                                        "Sticky broadcast " + intent + " for user "
18071                                        + userId + " conflicts with existing global broadcast");
18072                            }
18073                        }
18074                    }
18075                }
18076            }
18077            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18078            if (stickies == null) {
18079                stickies = new ArrayMap<>();
18080                mStickyBroadcasts.put(userId, stickies);
18081            }
18082            ArrayList<Intent> list = stickies.get(intent.getAction());
18083            if (list == null) {
18084                list = new ArrayList<>();
18085                stickies.put(intent.getAction(), list);
18086            }
18087            final int stickiesCount = list.size();
18088            int i;
18089            for (i = 0; i < stickiesCount; i++) {
18090                if (intent.filterEquals(list.get(i))) {
18091                    // This sticky already exists, replace it.
18092                    list.set(i, new Intent(intent));
18093                    break;
18094                }
18095            }
18096            if (i >= stickiesCount) {
18097                list.add(new Intent(intent));
18098            }
18099        }
18100
18101        int[] users;
18102        if (userId == UserHandle.USER_ALL) {
18103            // Caller wants broadcast to go to all started users.
18104            users = mUserController.getStartedUserArrayLocked();
18105        } else {
18106            // Caller wants broadcast to go to one specific user.
18107            users = new int[] {userId};
18108        }
18109
18110        // Figure out who all will receive this broadcast.
18111        List receivers = null;
18112        List<BroadcastFilter> registeredReceivers = null;
18113        // Need to resolve the intent to interested receivers...
18114        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18115                 == 0) {
18116            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18117        }
18118        if (intent.getComponent() == null) {
18119            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18120                // Query one target user at a time, excluding shell-restricted users
18121                for (int i = 0; i < users.length; i++) {
18122                    if (mUserController.hasUserRestriction(
18123                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18124                        continue;
18125                    }
18126                    List<BroadcastFilter> registeredReceiversForUser =
18127                            mReceiverResolver.queryIntent(intent,
18128                                    resolvedType, false, users[i]);
18129                    if (registeredReceivers == null) {
18130                        registeredReceivers = registeredReceiversForUser;
18131                    } else if (registeredReceiversForUser != null) {
18132                        registeredReceivers.addAll(registeredReceiversForUser);
18133                    }
18134                }
18135            } else {
18136                registeredReceivers = mReceiverResolver.queryIntent(intent,
18137                        resolvedType, false, userId);
18138            }
18139        }
18140
18141        final boolean replacePending =
18142                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18143
18144        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18145                + " replacePending=" + replacePending);
18146
18147        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18148        if (!ordered && NR > 0) {
18149            // If we are not serializing this broadcast, then send the
18150            // registered receivers separately so they don't wait for the
18151            // components to be launched.
18152            if (isCallerSystem) {
18153                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18154                        isProtectedBroadcast, registeredReceivers);
18155            }
18156            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18157            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18158                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18159                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18160                    resultExtras, ordered, sticky, false, userId);
18161            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18162            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18163            if (!replaced) {
18164                queue.enqueueParallelBroadcastLocked(r);
18165                queue.scheduleBroadcastsLocked();
18166            }
18167            registeredReceivers = null;
18168            NR = 0;
18169        }
18170
18171        // Merge into one list.
18172        int ir = 0;
18173        if (receivers != null) {
18174            // A special case for PACKAGE_ADDED: do not allow the package
18175            // being added to see this broadcast.  This prevents them from
18176            // using this as a back door to get run as soon as they are
18177            // installed.  Maybe in the future we want to have a special install
18178            // broadcast or such for apps, but we'd like to deliberately make
18179            // this decision.
18180            String skipPackages[] = null;
18181            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18182                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18183                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18184                Uri data = intent.getData();
18185                if (data != null) {
18186                    String pkgName = data.getSchemeSpecificPart();
18187                    if (pkgName != null) {
18188                        skipPackages = new String[] { pkgName };
18189                    }
18190                }
18191            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18192                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18193            }
18194            if (skipPackages != null && (skipPackages.length > 0)) {
18195                for (String skipPackage : skipPackages) {
18196                    if (skipPackage != null) {
18197                        int NT = receivers.size();
18198                        for (int it=0; it<NT; it++) {
18199                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18200                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18201                                receivers.remove(it);
18202                                it--;
18203                                NT--;
18204                            }
18205                        }
18206                    }
18207                }
18208            }
18209
18210            int NT = receivers != null ? receivers.size() : 0;
18211            int it = 0;
18212            ResolveInfo curt = null;
18213            BroadcastFilter curr = null;
18214            while (it < NT && ir < NR) {
18215                if (curt == null) {
18216                    curt = (ResolveInfo)receivers.get(it);
18217                }
18218                if (curr == null) {
18219                    curr = registeredReceivers.get(ir);
18220                }
18221                if (curr.getPriority() >= curt.priority) {
18222                    // Insert this broadcast record into the final list.
18223                    receivers.add(it, curr);
18224                    ir++;
18225                    curr = null;
18226                    it++;
18227                    NT++;
18228                } else {
18229                    // Skip to the next ResolveInfo in the final list.
18230                    it++;
18231                    curt = null;
18232                }
18233            }
18234        }
18235        while (ir < NR) {
18236            if (receivers == null) {
18237                receivers = new ArrayList();
18238            }
18239            receivers.add(registeredReceivers.get(ir));
18240            ir++;
18241        }
18242
18243        if (isCallerSystem) {
18244            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18245                    isProtectedBroadcast, receivers);
18246        }
18247
18248        if ((receivers != null && receivers.size() > 0)
18249                || resultTo != null) {
18250            BroadcastQueue queue = broadcastQueueForIntent(intent);
18251            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18252                    callerPackage, callingPid, callingUid, resolvedType,
18253                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18254                    resultData, resultExtras, ordered, sticky, false, userId);
18255
18256            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18257                    + ": prev had " + queue.mOrderedBroadcasts.size());
18258            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18259                    "Enqueueing broadcast " + r.intent.getAction());
18260
18261            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18262            if (!replaced) {
18263                queue.enqueueOrderedBroadcastLocked(r);
18264                queue.scheduleBroadcastsLocked();
18265            }
18266        } else {
18267            // There was nobody interested in the broadcast, but we still want to record
18268            // that it happened.
18269            if (intent.getComponent() == null && intent.getPackage() == null
18270                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18271                // This was an implicit broadcast... let's record it for posterity.
18272                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18273            }
18274        }
18275
18276        return ActivityManager.BROADCAST_SUCCESS;
18277    }
18278
18279    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18280            int skipCount, long dispatchTime) {
18281        final long now = SystemClock.elapsedRealtime();
18282        if (mCurBroadcastStats == null ||
18283                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18284            mLastBroadcastStats = mCurBroadcastStats;
18285            if (mLastBroadcastStats != null) {
18286                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18287                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18288            }
18289            mCurBroadcastStats = new BroadcastStats();
18290        }
18291        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18292    }
18293
18294    final Intent verifyBroadcastLocked(Intent intent) {
18295        // Refuse possible leaked file descriptors
18296        if (intent != null && intent.hasFileDescriptors() == true) {
18297            throw new IllegalArgumentException("File descriptors passed in Intent");
18298        }
18299
18300        int flags = intent.getFlags();
18301
18302        if (!mProcessesReady) {
18303            // if the caller really truly claims to know what they're doing, go
18304            // ahead and allow the broadcast without launching any receivers
18305            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18306                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18307            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18308                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18309                        + " before boot completion");
18310                throw new IllegalStateException("Cannot broadcast before boot completed");
18311            }
18312        }
18313
18314        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18315            throw new IllegalArgumentException(
18316                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18317        }
18318
18319        return intent;
18320    }
18321
18322    public final int broadcastIntent(IApplicationThread caller,
18323            Intent intent, String resolvedType, IIntentReceiver resultTo,
18324            int resultCode, String resultData, Bundle resultExtras,
18325            String[] requiredPermissions, int appOp, Bundle bOptions,
18326            boolean serialized, boolean sticky, int userId) {
18327        enforceNotIsolatedCaller("broadcastIntent");
18328        synchronized(this) {
18329            intent = verifyBroadcastLocked(intent);
18330
18331            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18332            final int callingPid = Binder.getCallingPid();
18333            final int callingUid = Binder.getCallingUid();
18334            final long origId = Binder.clearCallingIdentity();
18335            int res = broadcastIntentLocked(callerApp,
18336                    callerApp != null ? callerApp.info.packageName : null,
18337                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18338                    requiredPermissions, appOp, bOptions, serialized, sticky,
18339                    callingPid, callingUid, userId);
18340            Binder.restoreCallingIdentity(origId);
18341            return res;
18342        }
18343    }
18344
18345
18346    int broadcastIntentInPackage(String packageName, int uid,
18347            Intent intent, String resolvedType, IIntentReceiver resultTo,
18348            int resultCode, String resultData, Bundle resultExtras,
18349            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18350            int userId) {
18351        synchronized(this) {
18352            intent = verifyBroadcastLocked(intent);
18353
18354            final long origId = Binder.clearCallingIdentity();
18355            String[] requiredPermissions = requiredPermission == null ? null
18356                    : new String[] {requiredPermission};
18357            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18358                    resultTo, resultCode, resultData, resultExtras,
18359                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18360                    sticky, -1, uid, userId);
18361            Binder.restoreCallingIdentity(origId);
18362            return res;
18363        }
18364    }
18365
18366    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18367        // Refuse possible leaked file descriptors
18368        if (intent != null && intent.hasFileDescriptors() == true) {
18369            throw new IllegalArgumentException("File descriptors passed in Intent");
18370        }
18371
18372        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18373                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18374
18375        synchronized(this) {
18376            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18377                    != PackageManager.PERMISSION_GRANTED) {
18378                String msg = "Permission Denial: unbroadcastIntent() from pid="
18379                        + Binder.getCallingPid()
18380                        + ", uid=" + Binder.getCallingUid()
18381                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18382                Slog.w(TAG, msg);
18383                throw new SecurityException(msg);
18384            }
18385            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18386            if (stickies != null) {
18387                ArrayList<Intent> list = stickies.get(intent.getAction());
18388                if (list != null) {
18389                    int N = list.size();
18390                    int i;
18391                    for (i=0; i<N; i++) {
18392                        if (intent.filterEquals(list.get(i))) {
18393                            list.remove(i);
18394                            break;
18395                        }
18396                    }
18397                    if (list.size() <= 0) {
18398                        stickies.remove(intent.getAction());
18399                    }
18400                }
18401                if (stickies.size() <= 0) {
18402                    mStickyBroadcasts.remove(userId);
18403                }
18404            }
18405        }
18406    }
18407
18408    void backgroundServicesFinishedLocked(int userId) {
18409        for (BroadcastQueue queue : mBroadcastQueues) {
18410            queue.backgroundServicesFinishedLocked(userId);
18411        }
18412    }
18413
18414    public void finishReceiver(IBinder who, int resultCode, String resultData,
18415            Bundle resultExtras, boolean resultAbort, int flags) {
18416        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18417
18418        // Refuse possible leaked file descriptors
18419        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18420            throw new IllegalArgumentException("File descriptors passed in Bundle");
18421        }
18422
18423        final long origId = Binder.clearCallingIdentity();
18424        try {
18425            boolean doNext = false;
18426            BroadcastRecord r;
18427
18428            synchronized(this) {
18429                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18430                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18431                r = queue.getMatchingOrderedReceiver(who);
18432                if (r != null) {
18433                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18434                        resultData, resultExtras, resultAbort, true);
18435                }
18436            }
18437
18438            if (doNext) {
18439                r.queue.processNextBroadcast(false);
18440            }
18441            trimApplications();
18442        } finally {
18443            Binder.restoreCallingIdentity(origId);
18444        }
18445    }
18446
18447    // =========================================================
18448    // INSTRUMENTATION
18449    // =========================================================
18450
18451    public boolean startInstrumentation(ComponentName className,
18452            String profileFile, int flags, Bundle arguments,
18453            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18454            int userId, String abiOverride) {
18455        enforceNotIsolatedCaller("startInstrumentation");
18456        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18457                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18458        // Refuse possible leaked file descriptors
18459        if (arguments != null && arguments.hasFileDescriptors()) {
18460            throw new IllegalArgumentException("File descriptors passed in Bundle");
18461        }
18462
18463        synchronized(this) {
18464            InstrumentationInfo ii = null;
18465            ApplicationInfo ai = null;
18466            try {
18467                ii = mContext.getPackageManager().getInstrumentationInfo(
18468                    className, STOCK_PM_FLAGS);
18469                ai = AppGlobals.getPackageManager().getApplicationInfo(
18470                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18471            } catch (PackageManager.NameNotFoundException e) {
18472            } catch (RemoteException e) {
18473            }
18474            if (ii == null) {
18475                reportStartInstrumentationFailureLocked(watcher, className,
18476                        "Unable to find instrumentation info for: " + className);
18477                return false;
18478            }
18479            if (ai == null) {
18480                reportStartInstrumentationFailureLocked(watcher, className,
18481                        "Unable to find instrumentation target package: " + ii.targetPackage);
18482                return false;
18483            }
18484            if (!ai.hasCode()) {
18485                reportStartInstrumentationFailureLocked(watcher, className,
18486                        "Instrumentation target has no code: " + ii.targetPackage);
18487                return false;
18488            }
18489
18490            int match = mContext.getPackageManager().checkSignatures(
18491                    ii.targetPackage, ii.packageName);
18492            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18493                String msg = "Permission Denial: starting instrumentation "
18494                        + className + " from pid="
18495                        + Binder.getCallingPid()
18496                        + ", uid=" + Binder.getCallingPid()
18497                        + " not allowed because package " + ii.packageName
18498                        + " does not have a signature matching the target "
18499                        + ii.targetPackage;
18500                reportStartInstrumentationFailureLocked(watcher, className, msg);
18501                throw new SecurityException(msg);
18502            }
18503
18504            final long origId = Binder.clearCallingIdentity();
18505            // Instrumentation can kill and relaunch even persistent processes
18506            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18507                    "start instr");
18508            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18509            app.instrumentationClass = className;
18510            app.instrumentationInfo = ai;
18511            app.instrumentationProfileFile = profileFile;
18512            app.instrumentationArguments = arguments;
18513            app.instrumentationWatcher = watcher;
18514            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18515            app.instrumentationResultClass = className;
18516            Binder.restoreCallingIdentity(origId);
18517        }
18518
18519        return true;
18520    }
18521
18522    /**
18523     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18524     * error to the logs, but if somebody is watching, send the report there too.  This enables
18525     * the "am" command to report errors with more information.
18526     *
18527     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18528     * @param cn The component name of the instrumentation.
18529     * @param report The error report.
18530     */
18531    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18532            ComponentName cn, String report) {
18533        Slog.w(TAG, report);
18534        if (watcher != null) {
18535            Bundle results = new Bundle();
18536            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18537            results.putString("Error", report);
18538            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18539        }
18540    }
18541
18542    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18543        if (app.instrumentationWatcher != null) {
18544            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18545                    app.instrumentationClass, resultCode, results);
18546        }
18547
18548        // Can't call out of the system process with a lock held, so post a message.
18549        if (app.instrumentationUiAutomationConnection != null) {
18550            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18551                    app.instrumentationUiAutomationConnection).sendToTarget();
18552        }
18553
18554        app.instrumentationWatcher = null;
18555        app.instrumentationUiAutomationConnection = null;
18556        app.instrumentationClass = null;
18557        app.instrumentationInfo = null;
18558        app.instrumentationProfileFile = null;
18559        app.instrumentationArguments = null;
18560
18561        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18562                "finished inst");
18563    }
18564
18565    public void finishInstrumentation(IApplicationThread target,
18566            int resultCode, Bundle results) {
18567        int userId = UserHandle.getCallingUserId();
18568        // Refuse possible leaked file descriptors
18569        if (results != null && results.hasFileDescriptors()) {
18570            throw new IllegalArgumentException("File descriptors passed in Intent");
18571        }
18572
18573        synchronized(this) {
18574            ProcessRecord app = getRecordForAppLocked(target);
18575            if (app == null) {
18576                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18577                return;
18578            }
18579            final long origId = Binder.clearCallingIdentity();
18580            finishInstrumentationLocked(app, resultCode, results);
18581            Binder.restoreCallingIdentity(origId);
18582        }
18583    }
18584
18585    // =========================================================
18586    // CONFIGURATION
18587    // =========================================================
18588
18589    public ConfigurationInfo getDeviceConfigurationInfo() {
18590        ConfigurationInfo config = new ConfigurationInfo();
18591        synchronized (this) {
18592            final Configuration globalConfig = getGlobalConfiguration();
18593            config.reqTouchScreen = globalConfig.touchscreen;
18594            config.reqKeyboardType = globalConfig.keyboard;
18595            config.reqNavigation = globalConfig.navigation;
18596            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18597                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18598                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18599            }
18600            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18601                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18602                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18603            }
18604            config.reqGlEsVersion = GL_ES_VERSION;
18605        }
18606        return config;
18607    }
18608
18609    ActivityStack getFocusedStack() {
18610        return mStackSupervisor.getFocusedStack();
18611    }
18612
18613    @Override
18614    public int getFocusedStackId() throws RemoteException {
18615        ActivityStack focusedStack = getFocusedStack();
18616        if (focusedStack != null) {
18617            return focusedStack.getStackId();
18618        }
18619        return -1;
18620    }
18621
18622    public Configuration getConfiguration() {
18623        Configuration ci;
18624        synchronized(this) {
18625            ci = new Configuration(getGlobalConfiguration());
18626            ci.userSetLocale = false;
18627        }
18628        return ci;
18629    }
18630
18631    @Override
18632    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18633        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18634        synchronized (this) {
18635            mSuppressResizeConfigChanges = suppress;
18636        }
18637    }
18638
18639    @Override
18640    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18641        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18642        if (fromStackId == HOME_STACK_ID) {
18643            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18644        }
18645        synchronized (this) {
18646            final long origId = Binder.clearCallingIdentity();
18647            try {
18648                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18649            } finally {
18650                Binder.restoreCallingIdentity(origId);
18651            }
18652        }
18653    }
18654
18655    @Override
18656    public void updatePersistentConfiguration(Configuration values) {
18657        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
18658        enforceWriteSettingsPermission("updatePersistentConfiguration()");
18659        if (values == null) {
18660            throw new NullPointerException("Configuration must not be null");
18661        }
18662
18663        int userId = UserHandle.getCallingUserId();
18664
18665        synchronized(this) {
18666            updatePersistentConfigurationLocked(values, userId);
18667        }
18668    }
18669
18670    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18671        final long origId = Binder.clearCallingIdentity();
18672        try {
18673            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18674        } finally {
18675            Binder.restoreCallingIdentity(origId);
18676        }
18677    }
18678
18679    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18680        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18681                FONT_SCALE, 1.0f, userId);
18682
18683        synchronized (this) {
18684            if (getGlobalConfiguration().fontScale == scaleFactor) {
18685                return;
18686            }
18687
18688            final Configuration configuration
18689                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18690            configuration.fontScale = scaleFactor;
18691            updatePersistentConfigurationLocked(configuration, userId);
18692        }
18693    }
18694
18695    private void enforceWriteSettingsPermission(String func) {
18696        int uid = Binder.getCallingUid();
18697        if (uid == Process.ROOT_UID) {
18698            return;
18699        }
18700
18701        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18702                Settings.getPackageNameForUid(mContext, uid), false)) {
18703            return;
18704        }
18705
18706        String msg = "Permission Denial: " + func + " from pid="
18707                + Binder.getCallingPid()
18708                + ", uid=" + uid
18709                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18710        Slog.w(TAG, msg);
18711        throw new SecurityException(msg);
18712    }
18713
18714    @Override
18715    public boolean updateConfiguration(Configuration values) {
18716        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
18717
18718        synchronized(this) {
18719            if (values == null && mWindowManager != null) {
18720                // sentinel: fetch the current configuration from the window manager
18721                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18722            }
18723
18724            if (mWindowManager != null) {
18725                // Update OOM levels based on display size.
18726                mProcessList.applyDisplaySize(mWindowManager);
18727            }
18728
18729            final long origId = Binder.clearCallingIdentity();
18730            try {
18731                if (values != null) {
18732                    Settings.System.clearConfiguration(values);
18733                }
18734                updateConfigurationLocked(values, null, false, false /* persistent */,
18735                        UserHandle.USER_NULL, false /* deferResume */,
18736                        mTmpUpdateConfigurationResult);
18737                return mTmpUpdateConfigurationResult.changes != 0;
18738            } finally {
18739                Binder.restoreCallingIdentity(origId);
18740            }
18741        }
18742    }
18743
18744    void updateUserConfigurationLocked() {
18745        final Configuration configuration = new Configuration(getGlobalConfiguration());
18746        final int currentUserId = mUserController.getCurrentUserIdLocked();
18747        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18748                currentUserId, Settings.System.canWrite(mContext));
18749        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
18750                false /* persistent */, currentUserId, false /* deferResume */);
18751    }
18752
18753    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18754            boolean initLocale) {
18755        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18756    }
18757
18758    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18759            boolean initLocale, boolean deferResume) {
18760        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18761        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18762                UserHandle.USER_NULL, deferResume);
18763    }
18764
18765    // To cache the list of supported system locales
18766    private String[] mSupportedSystemLocales = null;
18767
18768    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18769            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18770        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
18771                deferResume, null /* result */);
18772    }
18773
18774    /**
18775     * Do either or both things: (1) change the current configuration, and (2)
18776     * make sure the given activity is running with the (now) current
18777     * configuration.  Returns true if the activity has been left running, or
18778     * false if <var>starting</var> is being destroyed to match the new
18779     * configuration.
18780     *
18781     * @param userId is only used when persistent parameter is set to true to persist configuration
18782     *               for that particular user
18783     */
18784    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18785            boolean initLocale, boolean persistent, int userId, boolean deferResume,
18786            UpdateConfigurationResult result) {
18787        int changes = 0;
18788        boolean kept = true;
18789
18790        if (mWindowManager != null) {
18791            mWindowManager.deferSurfaceLayout();
18792        }
18793        try {
18794            if (values != null) {
18795                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
18796                        deferResume);
18797            }
18798
18799            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
18800        } finally {
18801            if (mWindowManager != null) {
18802                mWindowManager.continueSurfaceLayout();
18803            }
18804        }
18805
18806        if (result != null) {
18807            result.changes = changes;
18808            result.activityRelaunched = !kept;
18809        }
18810        return kept;
18811    }
18812
18813    /** Update default (global) configuration and notify listeners about changes. */
18814    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
18815            boolean persistent, int userId, boolean deferResume) {
18816        mTempConfig.setTo(getGlobalConfiguration());
18817        final int changes = mTempConfig.updateFrom(values);
18818        if (changes == 0) {
18819            return 0;
18820        }
18821
18822        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18823                "Updating global configuration to: " + values);
18824
18825        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18826
18827        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18828            final LocaleList locales = values.getLocales();
18829            int bestLocaleIndex = 0;
18830            if (locales.size() > 1) {
18831                if (mSupportedSystemLocales == null) {
18832                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
18833                }
18834                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
18835            }
18836            SystemProperties.set("persist.sys.locale",
18837                    locales.get(bestLocaleIndex).toLanguageTag());
18838            LocaleList.setDefault(locales, bestLocaleIndex);
18839            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18840                    locales.get(bestLocaleIndex)));
18841        }
18842
18843        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
18844        mTempConfig.seq = mConfigurationSeq;
18845
18846        // Update stored global config and notify everyone about the change.
18847        mStackSupervisor.onConfigurationChanged(mTempConfig);
18848
18849        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
18850        // TODO(multi-display): Update UsageEvents#Event to include displayId.
18851        mUsageStatsService.reportConfigurationChange(mTempConfig,
18852                mUserController.getCurrentUserIdLocked());
18853
18854        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
18855        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
18856
18857        AttributeCache ac = AttributeCache.instance();
18858        if (ac != null) {
18859            ac.updateConfiguration(mTempConfig);
18860        }
18861
18862        // Make sure all resources in our process are updated right now, so that anyone who is going
18863        // to retrieve resource values after we return will be sure to get the new ones. This is
18864        // especially important during boot, where the first config change needs to guarantee all
18865        // resources have that config before following boot code is executed.
18866        mSystemThread.applyConfigurationToResources(mTempConfig);
18867
18868        // We need another copy of global config because we're scheduling some calls instead of
18869        // running them in place. We need to be sure that object we send will be handled unchanged.
18870        final Configuration configCopy = new Configuration(mTempConfig);
18871        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18872            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18873            msg.obj = configCopy;
18874            msg.arg1 = userId;
18875            mHandler.sendMessage(msg);
18876        }
18877
18878        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18879            ProcessRecord app = mLruProcesses.get(i);
18880            try {
18881                if (app.thread != null) {
18882                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18883                            + app.processName + " new config " + configCopy);
18884                    app.thread.scheduleConfigurationChanged(configCopy);
18885                }
18886            } catch (Exception e) {
18887            }
18888        }
18889
18890        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18891        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
18892                | Intent.FLAG_RECEIVER_FOREGROUND);
18893        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
18894                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
18895                UserHandle.USER_ALL);
18896        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
18897            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18898            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18899            if (initLocale || !mProcessesReady) {
18900                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18901            }
18902            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
18903                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
18904                    UserHandle.USER_ALL);
18905        }
18906
18907        // Override configuration of the default display duplicates global config, so we need to
18908        // update it also. This will also notify WindowManager about changes.
18909        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
18910                DEFAULT_DISPLAY);
18911
18912        return changes;
18913    }
18914
18915    @Override
18916    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
18917        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
18918
18919        synchronized (this) {
18920            if (values == null && mWindowManager != null) {
18921                // sentinel: fetch the current configuration from the window manager
18922                values = mWindowManager.computeNewConfiguration(displayId);
18923            }
18924
18925            if (mWindowManager != null) {
18926                // Update OOM levels based on display size.
18927                mProcessList.applyDisplaySize(mWindowManager);
18928            }
18929
18930            final long origId = Binder.clearCallingIdentity();
18931            try {
18932                if (values != null) {
18933                    Settings.System.clearConfiguration(values);
18934                }
18935                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
18936                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
18937                return mTmpUpdateConfigurationResult.changes != 0;
18938            } finally {
18939                Binder.restoreCallingIdentity(origId);
18940            }
18941        }
18942    }
18943
18944    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
18945            boolean deferResume, int displayId) {
18946        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
18947                displayId, null /* result */);
18948    }
18949
18950    /**
18951     * Updates override configuration specific for the selected display. If no config is provided,
18952     * new one will be computed in WM based on current display info.
18953     */
18954    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
18955            ActivityRecord starting, boolean deferResume, int displayId,
18956            UpdateConfigurationResult result) {
18957        int changes = 0;
18958        boolean kept = true;
18959
18960        if (mWindowManager != null) {
18961            mWindowManager.deferSurfaceLayout();
18962        }
18963        try {
18964            if (values != null) {
18965                if (displayId == DEFAULT_DISPLAY) {
18966                    // Override configuration of the default display duplicates global config, so
18967                    // we're calling global config update instead for default display. It will also
18968                    // apply the correct override config.
18969                    changes = updateGlobalConfiguration(values, false /* initLocale */,
18970                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
18971                } else {
18972                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
18973                }
18974            }
18975
18976            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
18977        } finally {
18978            if (mWindowManager != null) {
18979                mWindowManager.continueSurfaceLayout();
18980            }
18981        }
18982
18983        if (result != null) {
18984            result.changes = changes;
18985            result.activityRelaunched = !kept;
18986        }
18987        return kept;
18988    }
18989
18990    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
18991            int displayId) {
18992        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
18993        final int changes = mTempConfig.updateFrom(values);
18994        if (changes == 0) {
18995            return 0;
18996        }
18997
18998        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
18999                + " for displayId=" + displayId);
19000        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19001
19002        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19003        if (isDensityChange) {
19004            // Reset the unsupported display size dialog.
19005            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19006
19007            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19008        }
19009
19010        // Update the configuration with WM first and check if any of the stacks need to be resized
19011        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19012        // necessary. This way we don't need to relaunch again afterwards in
19013        // ensureActivityConfigurationLocked().
19014        if (mWindowManager != null) {
19015            final int[] resizedStacks =
19016                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19017            if (resizedStacks != null) {
19018                for (int stackId : resizedStacks) {
19019                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19020                }
19021            }
19022        }
19023
19024        return changes;
19025    }
19026
19027    /** Applies latest configuration and/or visibility updates if needed. */
19028    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19029        boolean kept = true;
19030        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19031        // mainStack is null during startup.
19032        if (mainStack != null) {
19033            if (changes != 0 && starting == null) {
19034                // If the configuration changed, and the caller is not already
19035                // in the process of starting an activity, then find the top
19036                // activity to check if its configuration needs to change.
19037                starting = mainStack.topRunningActivityLocked();
19038            }
19039
19040            if (starting != null) {
19041                kept = starting.ensureActivityConfigurationLocked(changes,
19042                        false /* preserveWindow */);
19043                // And we need to make sure at this point that all other activities
19044                // are made visible with the correct configuration.
19045                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19046                        !PRESERVE_WINDOWS);
19047            }
19048        }
19049
19050        return kept;
19051    }
19052
19053    /** Helper method that requests bounds from WM and applies them to stack. */
19054    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19055        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19056        mStackSupervisor.resizeStackLocked(
19057                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19058                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19059    }
19060
19061    /**
19062     * Decide based on the configuration whether we should show the ANR,
19063     * crash, etc dialogs.  The idea is that if there is no affordance to
19064     * press the on-screen buttons, or the user experience would be more
19065     * greatly impacted than the crash itself, we shouldn't show the dialog.
19066     *
19067     * A thought: SystemUI might also want to get told about this, the Power
19068     * dialog / global actions also might want different behaviors.
19069     */
19070    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19071        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19072                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19073                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19074        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19075        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19076                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19077        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19078    }
19079
19080    @Override
19081    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19082        synchronized (this) {
19083            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19084            if (srec != null) {
19085                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19086            }
19087        }
19088        return false;
19089    }
19090
19091    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19092            Intent resultData) {
19093
19094        synchronized (this) {
19095            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19096            if (r != null) {
19097                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19098            }
19099            return false;
19100        }
19101    }
19102
19103    public int getLaunchedFromUid(IBinder activityToken) {
19104        ActivityRecord srec;
19105        synchronized (this) {
19106            srec = ActivityRecord.forTokenLocked(activityToken);
19107        }
19108        if (srec == null) {
19109            return -1;
19110        }
19111        return srec.launchedFromUid;
19112    }
19113
19114    public String getLaunchedFromPackage(IBinder activityToken) {
19115        ActivityRecord srec;
19116        synchronized (this) {
19117            srec = ActivityRecord.forTokenLocked(activityToken);
19118        }
19119        if (srec == null) {
19120            return null;
19121        }
19122        return srec.launchedFromPackage;
19123    }
19124
19125    // =========================================================
19126    // LIFETIME MANAGEMENT
19127    // =========================================================
19128
19129    // Returns whether the app is receiving broadcast.
19130    // If receiving, fetch all broadcast queues which the app is
19131    // the current [or imminent] receiver on.
19132    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19133            ArraySet<BroadcastQueue> receivingQueues) {
19134        if (!app.curReceivers.isEmpty()) {
19135            for (BroadcastRecord r : app.curReceivers) {
19136                receivingQueues.add(r.queue);
19137            }
19138            return true;
19139        }
19140
19141        // It's not the current receiver, but it might be starting up to become one
19142        for (BroadcastQueue queue : mBroadcastQueues) {
19143            final BroadcastRecord r = queue.mPendingBroadcast;
19144            if (r != null && r.curApp == app) {
19145                // found it; report which queue it's in
19146                receivingQueues.add(queue);
19147            }
19148        }
19149
19150        return !receivingQueues.isEmpty();
19151    }
19152
19153    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19154            int targetUid, ComponentName targetComponent, String targetProcess) {
19155        if (!mTrackingAssociations) {
19156            return null;
19157        }
19158        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19159                = mAssociations.get(targetUid);
19160        if (components == null) {
19161            components = new ArrayMap<>();
19162            mAssociations.put(targetUid, components);
19163        }
19164        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19165        if (sourceUids == null) {
19166            sourceUids = new SparseArray<>();
19167            components.put(targetComponent, sourceUids);
19168        }
19169        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19170        if (sourceProcesses == null) {
19171            sourceProcesses = new ArrayMap<>();
19172            sourceUids.put(sourceUid, sourceProcesses);
19173        }
19174        Association ass = sourceProcesses.get(sourceProcess);
19175        if (ass == null) {
19176            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19177                    targetProcess);
19178            sourceProcesses.put(sourceProcess, ass);
19179        }
19180        ass.mCount++;
19181        ass.mNesting++;
19182        if (ass.mNesting == 1) {
19183            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19184            ass.mLastState = sourceState;
19185        }
19186        return ass;
19187    }
19188
19189    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19190            ComponentName targetComponent) {
19191        if (!mTrackingAssociations) {
19192            return;
19193        }
19194        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19195                = mAssociations.get(targetUid);
19196        if (components == null) {
19197            return;
19198        }
19199        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19200        if (sourceUids == null) {
19201            return;
19202        }
19203        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19204        if (sourceProcesses == null) {
19205            return;
19206        }
19207        Association ass = sourceProcesses.get(sourceProcess);
19208        if (ass == null || ass.mNesting <= 0) {
19209            return;
19210        }
19211        ass.mNesting--;
19212        if (ass.mNesting == 0) {
19213            long uptime = SystemClock.uptimeMillis();
19214            ass.mTime += uptime - ass.mStartTime;
19215            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19216                    += uptime - ass.mLastStateUptime;
19217            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19218        }
19219    }
19220
19221    private void noteUidProcessState(final int uid, final int state) {
19222        mBatteryStatsService.noteUidProcessState(uid, state);
19223        if (mTrackingAssociations) {
19224            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19225                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19226                        = mAssociations.valueAt(i1);
19227                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19228                    SparseArray<ArrayMap<String, Association>> sourceUids
19229                            = targetComponents.valueAt(i2);
19230                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19231                    if (sourceProcesses != null) {
19232                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19233                            Association ass = sourceProcesses.valueAt(i4);
19234                            if (ass.mNesting >= 1) {
19235                                // currently associated
19236                                long uptime = SystemClock.uptimeMillis();
19237                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19238                                        += uptime - ass.mLastStateUptime;
19239                                ass.mLastState = state;
19240                                ass.mLastStateUptime = uptime;
19241                            }
19242                        }
19243                    }
19244                }
19245            }
19246        }
19247    }
19248
19249    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19250            boolean doingAll, long now) {
19251        if (mAdjSeq == app.adjSeq) {
19252            // This adjustment has already been computed.
19253            return app.curRawAdj;
19254        }
19255
19256        if (app.thread == null) {
19257            app.adjSeq = mAdjSeq;
19258            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19259            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19260            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19261        }
19262
19263        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19264        app.adjSource = null;
19265        app.adjTarget = null;
19266        app.empty = false;
19267        app.cached = false;
19268
19269        final int activitiesSize = app.activities.size();
19270
19271        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19272            // The max adjustment doesn't allow this app to be anything
19273            // below foreground, so it is not worth doing work for it.
19274            app.adjType = "fixed";
19275            app.adjSeq = mAdjSeq;
19276            app.curRawAdj = app.maxAdj;
19277            app.foregroundActivities = false;
19278            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19279            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19280            // System processes can do UI, and when they do we want to have
19281            // them trim their memory after the user leaves the UI.  To
19282            // facilitate this, here we need to determine whether or not it
19283            // is currently showing UI.
19284            app.systemNoUi = true;
19285            if (app == TOP_APP) {
19286                app.systemNoUi = false;
19287                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19288                app.adjType = "pers-top-activity";
19289            } else if (app.hasTopUi) {
19290                app.systemNoUi = false;
19291                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19292                app.adjType = "pers-top-ui";
19293            } else if (activitiesSize > 0) {
19294                for (int j = 0; j < activitiesSize; j++) {
19295                    final ActivityRecord r = app.activities.get(j);
19296                    if (r.visible) {
19297                        app.systemNoUi = false;
19298                    }
19299                }
19300            }
19301            if (!app.systemNoUi) {
19302                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19303            }
19304            return (app.curAdj=app.maxAdj);
19305        }
19306
19307        app.systemNoUi = false;
19308
19309        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19310
19311        // Determine the importance of the process, starting with most
19312        // important to least, and assign an appropriate OOM adjustment.
19313        int adj;
19314        int schedGroup;
19315        int procState;
19316        boolean foregroundActivities = false;
19317        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19318        if (app == TOP_APP) {
19319            // The last app on the list is the foreground app.
19320            adj = ProcessList.FOREGROUND_APP_ADJ;
19321            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19322            app.adjType = "top-activity";
19323            foregroundActivities = true;
19324            procState = PROCESS_STATE_CUR_TOP;
19325        } else if (app.instrumentationClass != null) {
19326            // Don't want to kill running instrumentation.
19327            adj = ProcessList.FOREGROUND_APP_ADJ;
19328            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19329            app.adjType = "instrumentation";
19330            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19331        } else if (isReceivingBroadcastLocked(app, queues)) {
19332            // An app that is currently receiving a broadcast also
19333            // counts as being in the foreground for OOM killer purposes.
19334            // It's placed in a sched group based on the nature of the
19335            // broadcast as reflected by which queue it's active in.
19336            adj = ProcessList.FOREGROUND_APP_ADJ;
19337            schedGroup = (queues.contains(mFgBroadcastQueue))
19338                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19339            app.adjType = "broadcast";
19340            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19341        } else if (app.executingServices.size() > 0) {
19342            // An app that is currently executing a service callback also
19343            // counts as being in the foreground.
19344            adj = ProcessList.FOREGROUND_APP_ADJ;
19345            schedGroup = app.execServicesFg ?
19346                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19347            app.adjType = "exec-service";
19348            procState = ActivityManager.PROCESS_STATE_SERVICE;
19349            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19350        } else {
19351            // As far as we know the process is empty.  We may change our mind later.
19352            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19353            // At this point we don't actually know the adjustment.  Use the cached adj
19354            // value that the caller wants us to.
19355            adj = cachedAdj;
19356            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19357            app.cached = true;
19358            app.empty = true;
19359            app.adjType = "cch-empty";
19360        }
19361
19362        // Examine all activities if not already foreground.
19363        if (!foregroundActivities && activitiesSize > 0) {
19364            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19365            for (int j = 0; j < activitiesSize; j++) {
19366                final ActivityRecord r = app.activities.get(j);
19367                if (r.app != app) {
19368                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19369                            + " instead of expected " + app);
19370                    if (r.app == null || (r.app.uid == app.uid)) {
19371                        // Only fix things up when they look sane
19372                        r.app = app;
19373                    } else {
19374                        continue;
19375                    }
19376                }
19377                if (r.visible) {
19378                    // App has a visible activity; only upgrade adjustment.
19379                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19380                        adj = ProcessList.VISIBLE_APP_ADJ;
19381                        app.adjType = "visible";
19382                    }
19383                    if (procState > PROCESS_STATE_CUR_TOP) {
19384                        procState = PROCESS_STATE_CUR_TOP;
19385                    }
19386                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19387                    app.cached = false;
19388                    app.empty = false;
19389                    foregroundActivities = true;
19390                    if (r.task != null && minLayer > 0) {
19391                        final int layer = r.task.mLayerRank;
19392                        if (layer >= 0 && minLayer > layer) {
19393                            minLayer = layer;
19394                        }
19395                    }
19396                    break;
19397                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19398                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19399                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19400                        app.adjType = "pausing";
19401                    }
19402                    if (procState > PROCESS_STATE_CUR_TOP) {
19403                        procState = PROCESS_STATE_CUR_TOP;
19404                    }
19405                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19406                    app.cached = false;
19407                    app.empty = false;
19408                    foregroundActivities = true;
19409                } else if (r.state == ActivityState.STOPPING) {
19410                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19411                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19412                        app.adjType = "stopping";
19413                    }
19414                    // For the process state, we will at this point consider the
19415                    // process to be cached.  It will be cached either as an activity
19416                    // or empty depending on whether the activity is finishing.  We do
19417                    // this so that we can treat the process as cached for purposes of
19418                    // memory trimming (determing current memory level, trim command to
19419                    // send to process) since there can be an arbitrary number of stopping
19420                    // processes and they should soon all go into the cached state.
19421                    if (!r.finishing) {
19422                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19423                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19424                        }
19425                    }
19426                    app.cached = false;
19427                    app.empty = false;
19428                    foregroundActivities = true;
19429                } else {
19430                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19431                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19432                        app.adjType = "cch-act";
19433                    }
19434                }
19435            }
19436            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19437                adj += minLayer;
19438            }
19439        }
19440
19441        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19442                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19443            if (app.foregroundServices) {
19444                // The user is aware of this app, so make it visible.
19445                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19446                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19447                app.cached = false;
19448                app.adjType = "fg-service";
19449                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19450            } else if (app.forcingToForeground != null) {
19451                // The user is aware of this app, so make it visible.
19452                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19453                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19454                app.cached = false;
19455                app.adjType = "force-fg";
19456                app.adjSource = app.forcingToForeground;
19457                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19458            }
19459        }
19460
19461        if (app == mHeavyWeightProcess) {
19462            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19463                // We don't want to kill the current heavy-weight process.
19464                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19465                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19466                app.cached = false;
19467                app.adjType = "heavy";
19468            }
19469            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19470                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19471            }
19472        }
19473
19474        if (app == mHomeProcess) {
19475            if (adj > ProcessList.HOME_APP_ADJ) {
19476                // This process is hosting what we currently consider to be the
19477                // home app, so we don't want to let it go into the background.
19478                adj = ProcessList.HOME_APP_ADJ;
19479                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19480                app.cached = false;
19481                app.adjType = "home";
19482            }
19483            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19484                procState = ActivityManager.PROCESS_STATE_HOME;
19485            }
19486        }
19487
19488        if (app == mPreviousProcess && app.activities.size() > 0) {
19489            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19490                // This was the previous process that showed UI to the user.
19491                // We want to try to keep it around more aggressively, to give
19492                // a good experience around switching between two apps.
19493                adj = ProcessList.PREVIOUS_APP_ADJ;
19494                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19495                app.cached = false;
19496                app.adjType = "previous";
19497            }
19498            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19499                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19500            }
19501        }
19502
19503        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19504                + " reason=" + app.adjType);
19505
19506        // By default, we use the computed adjustment.  It may be changed if
19507        // there are applications dependent on our services or providers, but
19508        // this gives us a baseline and makes sure we don't get into an
19509        // infinite recursion.
19510        app.adjSeq = mAdjSeq;
19511        app.curRawAdj = adj;
19512        app.hasStartedServices = false;
19513
19514        if (mBackupTarget != null && app == mBackupTarget.app) {
19515            // If possible we want to avoid killing apps while they're being backed up
19516            if (adj > ProcessList.BACKUP_APP_ADJ) {
19517                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19518                adj = ProcessList.BACKUP_APP_ADJ;
19519                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19520                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19521                }
19522                app.adjType = "backup";
19523                app.cached = false;
19524            }
19525            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19526                procState = ActivityManager.PROCESS_STATE_BACKUP;
19527            }
19528        }
19529
19530        boolean mayBeTop = false;
19531
19532        for (int is = app.services.size()-1;
19533                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19534                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19535                        || procState > ActivityManager.PROCESS_STATE_TOP);
19536                is--) {
19537            ServiceRecord s = app.services.valueAt(is);
19538            if (s.startRequested) {
19539                app.hasStartedServices = true;
19540                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19541                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19542                }
19543                if (app.hasShownUi && app != mHomeProcess) {
19544                    // If this process has shown some UI, let it immediately
19545                    // go to the LRU list because it may be pretty heavy with
19546                    // UI stuff.  We'll tag it with a label just to help
19547                    // debug and understand what is going on.
19548                    if (adj > ProcessList.SERVICE_ADJ) {
19549                        app.adjType = "cch-started-ui-services";
19550                    }
19551                } else {
19552                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19553                        // This service has seen some activity within
19554                        // recent memory, so we will keep its process ahead
19555                        // of the background processes.
19556                        if (adj > ProcessList.SERVICE_ADJ) {
19557                            adj = ProcessList.SERVICE_ADJ;
19558                            app.adjType = "started-services";
19559                            app.cached = false;
19560                        }
19561                    }
19562                    // If we have let the service slide into the background
19563                    // state, still have some text describing what it is doing
19564                    // even though the service no longer has an impact.
19565                    if (adj > ProcessList.SERVICE_ADJ) {
19566                        app.adjType = "cch-started-services";
19567                    }
19568                }
19569            }
19570
19571            for (int conni = s.connections.size()-1;
19572                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19573                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19574                            || procState > ActivityManager.PROCESS_STATE_TOP);
19575                    conni--) {
19576                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19577                for (int i = 0;
19578                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19579                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19580                                || procState > ActivityManager.PROCESS_STATE_TOP);
19581                        i++) {
19582                    // XXX should compute this based on the max of
19583                    // all connected clients.
19584                    ConnectionRecord cr = clist.get(i);
19585                    if (cr.binding.client == app) {
19586                        // Binding to ourself is not interesting.
19587                        continue;
19588                    }
19589
19590                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19591                        ProcessRecord client = cr.binding.client;
19592                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19593                                TOP_APP, doingAll, now);
19594                        int clientProcState = client.curProcState;
19595                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19596                            // If the other app is cached for any reason, for purposes here
19597                            // we are going to consider it empty.  The specific cached state
19598                            // doesn't propagate except under certain conditions.
19599                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19600                        }
19601                        String adjType = null;
19602                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19603                            // Not doing bind OOM management, so treat
19604                            // this guy more like a started service.
19605                            if (app.hasShownUi && app != mHomeProcess) {
19606                                // If this process has shown some UI, let it immediately
19607                                // go to the LRU list because it may be pretty heavy with
19608                                // UI stuff.  We'll tag it with a label just to help
19609                                // debug and understand what is going on.
19610                                if (adj > clientAdj) {
19611                                    adjType = "cch-bound-ui-services";
19612                                }
19613                                app.cached = false;
19614                                clientAdj = adj;
19615                                clientProcState = procState;
19616                            } else {
19617                                if (now >= (s.lastActivity
19618                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19619                                    // This service has not seen activity within
19620                                    // recent memory, so allow it to drop to the
19621                                    // LRU list if there is no other reason to keep
19622                                    // it around.  We'll also tag it with a label just
19623                                    // to help debug and undertand what is going on.
19624                                    if (adj > clientAdj) {
19625                                        adjType = "cch-bound-services";
19626                                    }
19627                                    clientAdj = adj;
19628                                }
19629                            }
19630                        }
19631                        if (adj > clientAdj) {
19632                            // If this process has recently shown UI, and
19633                            // the process that is binding to it is less
19634                            // important than being visible, then we don't
19635                            // care about the binding as much as we care
19636                            // about letting this process get into the LRU
19637                            // list to be killed and restarted if needed for
19638                            // memory.
19639                            if (app.hasShownUi && app != mHomeProcess
19640                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19641                                adjType = "cch-bound-ui-services";
19642                            } else {
19643                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19644                                        |Context.BIND_IMPORTANT)) != 0) {
19645                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19646                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19647                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19648                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19649                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19650                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19651                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19652                                    adj = clientAdj;
19653                                } else {
19654                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19655                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19656                                    }
19657                                }
19658                                if (!client.cached) {
19659                                    app.cached = false;
19660                                }
19661                                adjType = "service";
19662                            }
19663                        }
19664                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19665                            // This will treat important bound services identically to
19666                            // the top app, which may behave differently than generic
19667                            // foreground work.
19668                            if (client.curSchedGroup > schedGroup) {
19669                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19670                                    schedGroup = client.curSchedGroup;
19671                                } else {
19672                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19673                                }
19674                            }
19675                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19676                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19677                                    // Special handling of clients who are in the top state.
19678                                    // We *may* want to consider this process to be in the
19679                                    // top state as well, but only if there is not another
19680                                    // reason for it to be running.  Being on the top is a
19681                                    // special state, meaning you are specifically running
19682                                    // for the current top app.  If the process is already
19683                                    // running in the background for some other reason, it
19684                                    // is more important to continue considering it to be
19685                                    // in the background state.
19686                                    mayBeTop = true;
19687                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19688                                } else {
19689                                    // Special handling for above-top states (persistent
19690                                    // processes).  These should not bring the current process
19691                                    // into the top state, since they are not on top.  Instead
19692                                    // give them the best state after that.
19693                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19694                                        clientProcState =
19695                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19696                                    } else if (mWakefulness
19697                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19698                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19699                                                    != 0) {
19700                                        clientProcState =
19701                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19702                                    } else {
19703                                        clientProcState =
19704                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19705                                    }
19706                                }
19707                            }
19708                        } else {
19709                            if (clientProcState <
19710                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19711                                clientProcState =
19712                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19713                            }
19714                        }
19715                        if (procState > clientProcState) {
19716                            procState = clientProcState;
19717                        }
19718                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19719                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19720                            app.pendingUiClean = true;
19721                        }
19722                        if (adjType != null) {
19723                            app.adjType = adjType;
19724                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19725                                    .REASON_SERVICE_IN_USE;
19726                            app.adjSource = cr.binding.client;
19727                            app.adjSourceProcState = clientProcState;
19728                            app.adjTarget = s.name;
19729                        }
19730                    }
19731                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19732                        app.treatLikeActivity = true;
19733                    }
19734                    final ActivityRecord a = cr.activity;
19735                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19736                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19737                            (a.visible || a.state == ActivityState.RESUMED ||
19738                             a.state == ActivityState.PAUSING)) {
19739                            adj = ProcessList.FOREGROUND_APP_ADJ;
19740                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19741                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19742                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19743                                } else {
19744                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19745                                }
19746                            }
19747                            app.cached = false;
19748                            app.adjType = "service";
19749                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19750                                    .REASON_SERVICE_IN_USE;
19751                            app.adjSource = a;
19752                            app.adjSourceProcState = procState;
19753                            app.adjTarget = s.name;
19754                        }
19755                    }
19756                }
19757            }
19758        }
19759
19760        for (int provi = app.pubProviders.size()-1;
19761                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19762                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19763                        || procState > ActivityManager.PROCESS_STATE_TOP);
19764                provi--) {
19765            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19766            for (int i = cpr.connections.size()-1;
19767                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19768                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19769                            || procState > ActivityManager.PROCESS_STATE_TOP);
19770                    i--) {
19771                ContentProviderConnection conn = cpr.connections.get(i);
19772                ProcessRecord client = conn.client;
19773                if (client == app) {
19774                    // Being our own client is not interesting.
19775                    continue;
19776                }
19777                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19778                int clientProcState = client.curProcState;
19779                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19780                    // If the other app is cached for any reason, for purposes here
19781                    // we are going to consider it empty.
19782                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19783                }
19784                if (adj > clientAdj) {
19785                    if (app.hasShownUi && app != mHomeProcess
19786                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19787                        app.adjType = "cch-ui-provider";
19788                    } else {
19789                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19790                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19791                        app.adjType = "provider";
19792                    }
19793                    app.cached &= client.cached;
19794                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19795                            .REASON_PROVIDER_IN_USE;
19796                    app.adjSource = client;
19797                    app.adjSourceProcState = clientProcState;
19798                    app.adjTarget = cpr.name;
19799                }
19800                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19801                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19802                        // Special handling of clients who are in the top state.
19803                        // We *may* want to consider this process to be in the
19804                        // top state as well, but only if there is not another
19805                        // reason for it to be running.  Being on the top is a
19806                        // special state, meaning you are specifically running
19807                        // for the current top app.  If the process is already
19808                        // running in the background for some other reason, it
19809                        // is more important to continue considering it to be
19810                        // in the background state.
19811                        mayBeTop = true;
19812                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19813                    } else {
19814                        // Special handling for above-top states (persistent
19815                        // processes).  These should not bring the current process
19816                        // into the top state, since they are not on top.  Instead
19817                        // give them the best state after that.
19818                        clientProcState =
19819                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19820                    }
19821                }
19822                if (procState > clientProcState) {
19823                    procState = clientProcState;
19824                }
19825                if (client.curSchedGroup > schedGroup) {
19826                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19827                }
19828            }
19829            // If the provider has external (non-framework) process
19830            // dependencies, ensure that its adjustment is at least
19831            // FOREGROUND_APP_ADJ.
19832            if (cpr.hasExternalProcessHandles()) {
19833                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19834                    adj = ProcessList.FOREGROUND_APP_ADJ;
19835                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19836                    app.cached = false;
19837                    app.adjType = "provider";
19838                    app.adjTarget = cpr.name;
19839                }
19840                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19841                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19842                }
19843            }
19844        }
19845
19846        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19847            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19848                adj = ProcessList.PREVIOUS_APP_ADJ;
19849                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19850                app.cached = false;
19851                app.adjType = "provider";
19852            }
19853            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19854                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19855            }
19856        }
19857
19858        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19859            // A client of one of our services or providers is in the top state.  We
19860            // *may* want to be in the top state, but not if we are already running in
19861            // the background for some other reason.  For the decision here, we are going
19862            // to pick out a few specific states that we want to remain in when a client
19863            // is top (states that tend to be longer-term) and otherwise allow it to go
19864            // to the top state.
19865            switch (procState) {
19866                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19867                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19868                case ActivityManager.PROCESS_STATE_SERVICE:
19869                    // These all are longer-term states, so pull them up to the top
19870                    // of the background states, but not all the way to the top state.
19871                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19872                    break;
19873                default:
19874                    // Otherwise, top is a better choice, so take it.
19875                    procState = ActivityManager.PROCESS_STATE_TOP;
19876                    break;
19877            }
19878        }
19879
19880        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19881            if (app.hasClientActivities) {
19882                // This is a cached process, but with client activities.  Mark it so.
19883                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19884                app.adjType = "cch-client-act";
19885            } else if (app.treatLikeActivity) {
19886                // This is a cached process, but somebody wants us to treat it like it has
19887                // an activity, okay!
19888                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19889                app.adjType = "cch-as-act";
19890            }
19891        }
19892
19893        if (adj == ProcessList.SERVICE_ADJ) {
19894            if (doingAll) {
19895                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19896                mNewNumServiceProcs++;
19897                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19898                if (!app.serviceb) {
19899                    // This service isn't far enough down on the LRU list to
19900                    // normally be a B service, but if we are low on RAM and it
19901                    // is large we want to force it down since we would prefer to
19902                    // keep launcher over it.
19903                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19904                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19905                        app.serviceHighRam = true;
19906                        app.serviceb = true;
19907                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19908                    } else {
19909                        mNewNumAServiceProcs++;
19910                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19911                    }
19912                } else {
19913                    app.serviceHighRam = false;
19914                }
19915            }
19916            if (app.serviceb) {
19917                adj = ProcessList.SERVICE_B_ADJ;
19918            }
19919        }
19920
19921        app.curRawAdj = adj;
19922
19923        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19924        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19925        if (adj > app.maxAdj) {
19926            adj = app.maxAdj;
19927            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19928                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19929            }
19930        }
19931
19932        // Do final modification to adj.  Everything we do between here and applying
19933        // the final setAdj must be done in this function, because we will also use
19934        // it when computing the final cached adj later.  Note that we don't need to
19935        // worry about this for max adj above, since max adj will always be used to
19936        // keep it out of the cached vaues.
19937        app.curAdj = app.modifyRawOomAdj(adj);
19938        app.curSchedGroup = schedGroup;
19939        app.curProcState = procState;
19940        app.foregroundActivities = foregroundActivities;
19941
19942        return app.curRawAdj;
19943    }
19944
19945    /**
19946     * Record new PSS sample for a process.
19947     */
19948    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19949            long now) {
19950        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19951                swapPss * 1024);
19952        proc.lastPssTime = now;
19953        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19954        if (DEBUG_PSS) Slog.d(TAG_PSS,
19955                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19956                + " state=" + ProcessList.makeProcStateString(procState));
19957        if (proc.initialIdlePss == 0) {
19958            proc.initialIdlePss = pss;
19959        }
19960        proc.lastPss = pss;
19961        proc.lastSwapPss = swapPss;
19962        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19963            proc.lastCachedPss = pss;
19964            proc.lastCachedSwapPss = swapPss;
19965        }
19966
19967        final SparseArray<Pair<Long, String>> watchUids
19968                = mMemWatchProcesses.getMap().get(proc.processName);
19969        Long check = null;
19970        if (watchUids != null) {
19971            Pair<Long, String> val = watchUids.get(proc.uid);
19972            if (val == null) {
19973                val = watchUids.get(0);
19974            }
19975            if (val != null) {
19976                check = val.first;
19977            }
19978        }
19979        if (check != null) {
19980            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19981                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19982                if (!isDebuggable) {
19983                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19984                        isDebuggable = true;
19985                    }
19986                }
19987                if (isDebuggable) {
19988                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19989                    final ProcessRecord myProc = proc;
19990                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19991                    mMemWatchDumpProcName = proc.processName;
19992                    mMemWatchDumpFile = heapdumpFile.toString();
19993                    mMemWatchDumpPid = proc.pid;
19994                    mMemWatchDumpUid = proc.uid;
19995                    BackgroundThread.getHandler().post(new Runnable() {
19996                        @Override
19997                        public void run() {
19998                            revokeUriPermission(ActivityThread.currentActivityThread()
19999                                            .getApplicationThread(),
20000                                    DumpHeapActivity.JAVA_URI,
20001                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20002                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20003                                    UserHandle.myUserId());
20004                            ParcelFileDescriptor fd = null;
20005                            try {
20006                                heapdumpFile.delete();
20007                                fd = ParcelFileDescriptor.open(heapdumpFile,
20008                                        ParcelFileDescriptor.MODE_CREATE |
20009                                                ParcelFileDescriptor.MODE_TRUNCATE |
20010                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20011                                                ParcelFileDescriptor.MODE_APPEND);
20012                                IApplicationThread thread = myProc.thread;
20013                                if (thread != null) {
20014                                    try {
20015                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20016                                                "Requesting dump heap from "
20017                                                + myProc + " to " + heapdumpFile);
20018                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20019                                    } catch (RemoteException e) {
20020                                    }
20021                                }
20022                            } catch (FileNotFoundException e) {
20023                                e.printStackTrace();
20024                            } finally {
20025                                if (fd != null) {
20026                                    try {
20027                                        fd.close();
20028                                    } catch (IOException e) {
20029                                    }
20030                                }
20031                            }
20032                        }
20033                    });
20034                } else {
20035                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20036                            + ", but debugging not enabled");
20037                }
20038            }
20039        }
20040    }
20041
20042    /**
20043     * Schedule PSS collection of a process.
20044     */
20045    void requestPssLocked(ProcessRecord proc, int procState) {
20046        if (mPendingPssProcesses.contains(proc)) {
20047            return;
20048        }
20049        if (mPendingPssProcesses.size() == 0) {
20050            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20051        }
20052        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20053        proc.pssProcState = procState;
20054        mPendingPssProcesses.add(proc);
20055    }
20056
20057    /**
20058     * Schedule PSS collection of all processes.
20059     */
20060    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20061        if (!always) {
20062            if (now < (mLastFullPssTime +
20063                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20064                return;
20065            }
20066        }
20067        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20068        mLastFullPssTime = now;
20069        mFullPssPending = true;
20070        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20071        mPendingPssProcesses.clear();
20072        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20073            ProcessRecord app = mLruProcesses.get(i);
20074            if (app.thread == null
20075                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20076                continue;
20077            }
20078            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20079                app.pssProcState = app.setProcState;
20080                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20081                        mTestPssMode, isSleepingLocked(), now);
20082                mPendingPssProcesses.add(app);
20083            }
20084        }
20085        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20086    }
20087
20088    public void setTestPssMode(boolean enabled) {
20089        synchronized (this) {
20090            mTestPssMode = enabled;
20091            if (enabled) {
20092                // Whenever we enable the mode, we want to take a snapshot all of current
20093                // process mem use.
20094                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20095            }
20096        }
20097    }
20098
20099    /**
20100     * Ask a given process to GC right now.
20101     */
20102    final void performAppGcLocked(ProcessRecord app) {
20103        try {
20104            app.lastRequestedGc = SystemClock.uptimeMillis();
20105            if (app.thread != null) {
20106                if (app.reportLowMemory) {
20107                    app.reportLowMemory = false;
20108                    app.thread.scheduleLowMemory();
20109                } else {
20110                    app.thread.processInBackground();
20111                }
20112            }
20113        } catch (Exception e) {
20114            // whatever.
20115        }
20116    }
20117
20118    /**
20119     * Returns true if things are idle enough to perform GCs.
20120     */
20121    private final boolean canGcNowLocked() {
20122        boolean processingBroadcasts = false;
20123        for (BroadcastQueue q : mBroadcastQueues) {
20124            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20125                processingBroadcasts = true;
20126            }
20127        }
20128        return !processingBroadcasts
20129                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20130    }
20131
20132    /**
20133     * Perform GCs on all processes that are waiting for it, but only
20134     * if things are idle.
20135     */
20136    final void performAppGcsLocked() {
20137        final int N = mProcessesToGc.size();
20138        if (N <= 0) {
20139            return;
20140        }
20141        if (canGcNowLocked()) {
20142            while (mProcessesToGc.size() > 0) {
20143                ProcessRecord proc = mProcessesToGc.remove(0);
20144                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20145                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20146                            <= SystemClock.uptimeMillis()) {
20147                        // To avoid spamming the system, we will GC processes one
20148                        // at a time, waiting a few seconds between each.
20149                        performAppGcLocked(proc);
20150                        scheduleAppGcsLocked();
20151                        return;
20152                    } else {
20153                        // It hasn't been long enough since we last GCed this
20154                        // process...  put it in the list to wait for its time.
20155                        addProcessToGcListLocked(proc);
20156                        break;
20157                    }
20158                }
20159            }
20160
20161            scheduleAppGcsLocked();
20162        }
20163    }
20164
20165    /**
20166     * If all looks good, perform GCs on all processes waiting for them.
20167     */
20168    final void performAppGcsIfAppropriateLocked() {
20169        if (canGcNowLocked()) {
20170            performAppGcsLocked();
20171            return;
20172        }
20173        // Still not idle, wait some more.
20174        scheduleAppGcsLocked();
20175    }
20176
20177    /**
20178     * Schedule the execution of all pending app GCs.
20179     */
20180    final void scheduleAppGcsLocked() {
20181        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20182
20183        if (mProcessesToGc.size() > 0) {
20184            // Schedule a GC for the time to the next process.
20185            ProcessRecord proc = mProcessesToGc.get(0);
20186            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20187
20188            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20189            long now = SystemClock.uptimeMillis();
20190            if (when < (now+GC_TIMEOUT)) {
20191                when = now + GC_TIMEOUT;
20192            }
20193            mHandler.sendMessageAtTime(msg, when);
20194        }
20195    }
20196
20197    /**
20198     * Add a process to the array of processes waiting to be GCed.  Keeps the
20199     * list in sorted order by the last GC time.  The process can't already be
20200     * on the list.
20201     */
20202    final void addProcessToGcListLocked(ProcessRecord proc) {
20203        boolean added = false;
20204        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20205            if (mProcessesToGc.get(i).lastRequestedGc <
20206                    proc.lastRequestedGc) {
20207                added = true;
20208                mProcessesToGc.add(i+1, proc);
20209                break;
20210            }
20211        }
20212        if (!added) {
20213            mProcessesToGc.add(0, proc);
20214        }
20215    }
20216
20217    /**
20218     * Set up to ask a process to GC itself.  This will either do it
20219     * immediately, or put it on the list of processes to gc the next
20220     * time things are idle.
20221     */
20222    final void scheduleAppGcLocked(ProcessRecord app) {
20223        long now = SystemClock.uptimeMillis();
20224        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20225            return;
20226        }
20227        if (!mProcessesToGc.contains(app)) {
20228            addProcessToGcListLocked(app);
20229            scheduleAppGcsLocked();
20230        }
20231    }
20232
20233    final void checkExcessivePowerUsageLocked(boolean doKills) {
20234        updateCpuStatsNow();
20235
20236        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20237        boolean doWakeKills = doKills;
20238        boolean doCpuKills = doKills;
20239        if (mLastPowerCheckRealtime == 0) {
20240            doWakeKills = false;
20241        }
20242        if (mLastPowerCheckUptime == 0) {
20243            doCpuKills = false;
20244        }
20245        if (stats.isScreenOn()) {
20246            doWakeKills = false;
20247        }
20248        final long curRealtime = SystemClock.elapsedRealtime();
20249        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20250        final long curUptime = SystemClock.uptimeMillis();
20251        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20252        mLastPowerCheckRealtime = curRealtime;
20253        mLastPowerCheckUptime = curUptime;
20254        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20255            doWakeKills = false;
20256        }
20257        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20258            doCpuKills = false;
20259        }
20260        int i = mLruProcesses.size();
20261        while (i > 0) {
20262            i--;
20263            ProcessRecord app = mLruProcesses.get(i);
20264            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20265                long wtime;
20266                synchronized (stats) {
20267                    wtime = stats.getProcessWakeTime(app.info.uid,
20268                            app.pid, curRealtime);
20269                }
20270                long wtimeUsed = wtime - app.lastWakeTime;
20271                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20272                if (DEBUG_POWER) {
20273                    StringBuilder sb = new StringBuilder(128);
20274                    sb.append("Wake for ");
20275                    app.toShortString(sb);
20276                    sb.append(": over ");
20277                    TimeUtils.formatDuration(realtimeSince, sb);
20278                    sb.append(" used ");
20279                    TimeUtils.formatDuration(wtimeUsed, sb);
20280                    sb.append(" (");
20281                    sb.append((wtimeUsed*100)/realtimeSince);
20282                    sb.append("%)");
20283                    Slog.i(TAG_POWER, sb.toString());
20284                    sb.setLength(0);
20285                    sb.append("CPU for ");
20286                    app.toShortString(sb);
20287                    sb.append(": over ");
20288                    TimeUtils.formatDuration(uptimeSince, sb);
20289                    sb.append(" used ");
20290                    TimeUtils.formatDuration(cputimeUsed, sb);
20291                    sb.append(" (");
20292                    sb.append((cputimeUsed*100)/uptimeSince);
20293                    sb.append("%)");
20294                    Slog.i(TAG_POWER, sb.toString());
20295                }
20296                // If a process has held a wake lock for more
20297                // than 50% of the time during this period,
20298                // that sounds bad.  Kill!
20299                if (doWakeKills && realtimeSince > 0
20300                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20301                    synchronized (stats) {
20302                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20303                                realtimeSince, wtimeUsed);
20304                    }
20305                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20306                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20307                } else if (doCpuKills && uptimeSince > 0
20308                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20309                    synchronized (stats) {
20310                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20311                                uptimeSince, cputimeUsed);
20312                    }
20313                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20314                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20315                } else {
20316                    app.lastWakeTime = wtime;
20317                    app.lastCpuTime = app.curCpuTime;
20318                }
20319            }
20320        }
20321    }
20322
20323    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20324            long nowElapsed) {
20325        boolean success = true;
20326
20327        if (app.curRawAdj != app.setRawAdj) {
20328            app.setRawAdj = app.curRawAdj;
20329        }
20330
20331        int changes = 0;
20332
20333        if (app.curAdj != app.setAdj) {
20334            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20335            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20336                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20337                    + app.adjType);
20338            app.setAdj = app.curAdj;
20339            app.verifiedAdj = ProcessList.INVALID_ADJ;
20340        }
20341
20342        if (app.setSchedGroup != app.curSchedGroup) {
20343            int oldSchedGroup = app.setSchedGroup;
20344            app.setSchedGroup = app.curSchedGroup;
20345            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20346                    "Setting sched group of " + app.processName
20347                    + " to " + app.curSchedGroup);
20348            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20349                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20350                app.kill(app.waitingToKill, true);
20351                success = false;
20352            } else {
20353                int processGroup;
20354                switch (app.curSchedGroup) {
20355                    case ProcessList.SCHED_GROUP_BACKGROUND:
20356                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20357                        break;
20358                    case ProcessList.SCHED_GROUP_TOP_APP:
20359                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20360                        processGroup = Process.THREAD_GROUP_TOP_APP;
20361                        break;
20362                    default:
20363                        processGroup = Process.THREAD_GROUP_DEFAULT;
20364                        break;
20365                }
20366                long oldId = Binder.clearCallingIdentity();
20367                try {
20368                    Process.setProcessGroup(app.pid, processGroup);
20369                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20370                        // do nothing if we already switched to RT
20371                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20372                            // Switch VR thread for app to SCHED_FIFO
20373                            if (mInVrMode && app.vrThreadTid != 0) {
20374                                try {
20375                                    Process.setThreadScheduler(app.vrThreadTid,
20376                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20377                                } catch (IllegalArgumentException e) {
20378                                    // thread died, ignore
20379                                }
20380                            }
20381                            if (mUseFifoUiScheduling) {
20382                                // Switch UI pipeline for app to SCHED_FIFO
20383                                app.savedPriority = Process.getThreadPriority(app.pid);
20384                                try {
20385                                    Process.setThreadScheduler(app.pid,
20386                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20387                                } catch (IllegalArgumentException e) {
20388                                    // thread died, ignore
20389                                }
20390                                if (app.renderThreadTid != 0) {
20391                                    try {
20392                                        Process.setThreadScheduler(app.renderThreadTid,
20393                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20394                                    } catch (IllegalArgumentException e) {
20395                                        // thread died, ignore
20396                                    }
20397                                    if (DEBUG_OOM_ADJ) {
20398                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20399                                            app.renderThreadTid + ") to FIFO");
20400                                    }
20401                                } else {
20402                                    if (DEBUG_OOM_ADJ) {
20403                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20404                                    }
20405                                }
20406                            } else {
20407                                // Boost priority for top app UI and render threads
20408                                Process.setThreadPriority(app.pid, -10);
20409                                if (app.renderThreadTid != 0) {
20410                                    try {
20411                                        Process.setThreadPriority(app.renderThreadTid, -10);
20412                                    } catch (IllegalArgumentException e) {
20413                                        // thread died, ignore
20414                                    }
20415                                }
20416                            }
20417                        }
20418                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20419                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20420                        // Reset VR thread to SCHED_OTHER
20421                        // Safe to do even if we're not in VR mode
20422                        if (app.vrThreadTid != 0) {
20423                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20424                        }
20425                        if (mUseFifoUiScheduling) {
20426                            // Reset UI pipeline to SCHED_OTHER
20427                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20428                            Process.setThreadPriority(app.pid, app.savedPriority);
20429                            if (app.renderThreadTid != 0) {
20430                                Process.setThreadScheduler(app.renderThreadTid,
20431                                    Process.SCHED_OTHER, 0);
20432                                Process.setThreadPriority(app.renderThreadTid, -4);
20433                            }
20434                        } else {
20435                            // Reset priority for top app UI and render threads
20436                            Process.setThreadPriority(app.pid, 0);
20437                            if (app.renderThreadTid != 0) {
20438                                Process.setThreadPriority(app.renderThreadTid, 0);
20439                            }
20440                        }
20441                    }
20442                } catch (Exception e) {
20443                    Slog.w(TAG, "Failed setting process group of " + app.pid
20444                            + " to " + app.curSchedGroup);
20445                    e.printStackTrace();
20446                } finally {
20447                    Binder.restoreCallingIdentity(oldId);
20448                }
20449            }
20450        }
20451        if (app.repForegroundActivities != app.foregroundActivities) {
20452            app.repForegroundActivities = app.foregroundActivities;
20453            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20454        }
20455        if (app.repProcState != app.curProcState) {
20456            app.repProcState = app.curProcState;
20457            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20458            if (app.thread != null) {
20459                try {
20460                    if (false) {
20461                        //RuntimeException h = new RuntimeException("here");
20462                        Slog.i(TAG, "Sending new process state " + app.repProcState
20463                                + " to " + app /*, h*/);
20464                    }
20465                    app.thread.setProcessState(app.repProcState);
20466                } catch (RemoteException e) {
20467                }
20468            }
20469        }
20470        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20471                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20472            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20473                // Experimental code to more aggressively collect pss while
20474                // running test...  the problem is that this tends to collect
20475                // the data right when a process is transitioning between process
20476                // states, which well tend to give noisy data.
20477                long start = SystemClock.uptimeMillis();
20478                long pss = Debug.getPss(app.pid, mTmpLong, null);
20479                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20480                mPendingPssProcesses.remove(app);
20481                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20482                        + " to " + app.curProcState + ": "
20483                        + (SystemClock.uptimeMillis()-start) + "ms");
20484            }
20485            app.lastStateTime = now;
20486            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20487                    mTestPssMode, isSleepingLocked(), now);
20488            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20489                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20490                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20491                    + (app.nextPssTime-now) + ": " + app);
20492        } else {
20493            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20494                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20495                    mTestPssMode)))) {
20496                requestPssLocked(app, app.setProcState);
20497                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20498                        mTestPssMode, isSleepingLocked(), now);
20499            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20500                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20501        }
20502        if (app.setProcState != app.curProcState) {
20503            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20504                    "Proc state change of " + app.processName
20505                            + " to " + app.curProcState);
20506            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20507            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20508            if (setImportant && !curImportant) {
20509                // This app is no longer something we consider important enough to allow to
20510                // use arbitrary amounts of battery power.  Note
20511                // its current wake lock time to later know to kill it if
20512                // it is not behaving well.
20513                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20514                synchronized (stats) {
20515                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20516                            app.pid, nowElapsed);
20517                }
20518                app.lastCpuTime = app.curCpuTime;
20519
20520            }
20521            // Inform UsageStats of important process state change
20522            // Must be called before updating setProcState
20523            maybeUpdateUsageStatsLocked(app, nowElapsed);
20524
20525            app.setProcState = app.curProcState;
20526            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20527                app.notCachedSinceIdle = false;
20528            }
20529            if (!doingAll) {
20530                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20531            } else {
20532                app.procStateChanged = true;
20533            }
20534        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20535                > USAGE_STATS_INTERACTION_INTERVAL) {
20536            // For apps that sit around for a long time in the interactive state, we need
20537            // to report this at least once a day so they don't go idle.
20538            maybeUpdateUsageStatsLocked(app, nowElapsed);
20539        }
20540
20541        if (changes != 0) {
20542            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20543                    "Changes in " + app + ": " + changes);
20544            int i = mPendingProcessChanges.size()-1;
20545            ProcessChangeItem item = null;
20546            while (i >= 0) {
20547                item = mPendingProcessChanges.get(i);
20548                if (item.pid == app.pid) {
20549                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20550                            "Re-using existing item: " + item);
20551                    break;
20552                }
20553                i--;
20554            }
20555            if (i < 0) {
20556                // No existing item in pending changes; need a new one.
20557                final int NA = mAvailProcessChanges.size();
20558                if (NA > 0) {
20559                    item = mAvailProcessChanges.remove(NA-1);
20560                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20561                            "Retrieving available item: " + item);
20562                } else {
20563                    item = new ProcessChangeItem();
20564                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20565                            "Allocating new item: " + item);
20566                }
20567                item.changes = 0;
20568                item.pid = app.pid;
20569                item.uid = app.info.uid;
20570                if (mPendingProcessChanges.size() == 0) {
20571                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20572                            "*** Enqueueing dispatch processes changed!");
20573                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20574                }
20575                mPendingProcessChanges.add(item);
20576            }
20577            item.changes |= changes;
20578            item.processState = app.repProcState;
20579            item.foregroundActivities = app.repForegroundActivities;
20580            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20581                    "Item " + Integer.toHexString(System.identityHashCode(item))
20582                    + " " + app.toShortString() + ": changes=" + item.changes
20583                    + " procState=" + item.processState
20584                    + " foreground=" + item.foregroundActivities
20585                    + " type=" + app.adjType + " source=" + app.adjSource
20586                    + " target=" + app.adjTarget);
20587        }
20588
20589        return success;
20590    }
20591
20592    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20593        final UidRecord.ChangeItem pendingChange;
20594        if (uidRec == null || uidRec.pendingChange == null) {
20595            if (mPendingUidChanges.size() == 0) {
20596                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20597                        "*** Enqueueing dispatch uid changed!");
20598                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20599            }
20600            final int NA = mAvailUidChanges.size();
20601            if (NA > 0) {
20602                pendingChange = mAvailUidChanges.remove(NA-1);
20603                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20604                        "Retrieving available item: " + pendingChange);
20605            } else {
20606                pendingChange = new UidRecord.ChangeItem();
20607                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20608                        "Allocating new item: " + pendingChange);
20609            }
20610            if (uidRec != null) {
20611                uidRec.pendingChange = pendingChange;
20612                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20613                    // If this uid is going away, and we haven't yet reported it is gone,
20614                    // then do so now.
20615                    change = UidRecord.CHANGE_GONE_IDLE;
20616                }
20617            } else if (uid < 0) {
20618                throw new IllegalArgumentException("No UidRecord or uid");
20619            }
20620            pendingChange.uidRecord = uidRec;
20621            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20622            mPendingUidChanges.add(pendingChange);
20623        } else {
20624            pendingChange = uidRec.pendingChange;
20625            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20626                change = UidRecord.CHANGE_GONE_IDLE;
20627            }
20628        }
20629        pendingChange.change = change;
20630        pendingChange.processState = uidRec != null
20631                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20632
20633        // Directly update the power manager, since we sit on top of it and it is critical
20634        // it be kept in sync (so wake locks will be held as soon as appropriate).
20635        if (mLocalPowerManager != null) {
20636            switch (change) {
20637                case UidRecord.CHANGE_GONE:
20638                case UidRecord.CHANGE_GONE_IDLE:
20639                    mLocalPowerManager.uidGone(pendingChange.uid);
20640                    break;
20641                case UidRecord.CHANGE_IDLE:
20642                    mLocalPowerManager.uidIdle(pendingChange.uid);
20643                    break;
20644                case UidRecord.CHANGE_ACTIVE:
20645                    mLocalPowerManager.uidActive(pendingChange.uid);
20646                    break;
20647                default:
20648                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
20649                            pendingChange.processState);
20650                    break;
20651            }
20652        }
20653    }
20654
20655    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20656            String authority) {
20657        if (app == null) return;
20658        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20659            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20660            if (userState == null) return;
20661            final long now = SystemClock.elapsedRealtime();
20662            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20663            if (lastReported == null || lastReported < now - 60 * 1000L) {
20664                if (mSystemReady) {
20665                    // Cannot touch the user stats if not system ready
20666                    mUsageStatsService.reportContentProviderUsage(
20667                            authority, providerPkgName, app.userId);
20668                }
20669                userState.mProviderLastReportedFg.put(authority, now);
20670            }
20671        }
20672    }
20673
20674    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20675        if (DEBUG_USAGE_STATS) {
20676            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20677                    + "] state changes: old = " + app.setProcState + ", new = "
20678                    + app.curProcState);
20679        }
20680        if (mUsageStatsService == null) {
20681            return;
20682        }
20683        boolean isInteraction;
20684        // To avoid some abuse patterns, we are going to be careful about what we consider
20685        // to be an app interaction.  Being the top activity doesn't count while the display
20686        // is sleeping, nor do short foreground services.
20687        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20688            isInteraction = true;
20689            app.fgInteractionTime = 0;
20690        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20691            if (app.fgInteractionTime == 0) {
20692                app.fgInteractionTime = nowElapsed;
20693                isInteraction = false;
20694            } else {
20695                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20696            }
20697        } else {
20698            // If the app was being forced to the foreground, by say a Toast, then
20699            // no need to treat it as an interaction
20700            isInteraction = app.forcingToForeground == null
20701                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20702            app.fgInteractionTime = 0;
20703        }
20704        if (isInteraction && (!app.reportedInteraction
20705                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20706            app.interactionEventTime = nowElapsed;
20707            String[] packages = app.getPackageList();
20708            if (packages != null) {
20709                for (int i = 0; i < packages.length; i++) {
20710                    mUsageStatsService.reportEvent(packages[i], app.userId,
20711                            UsageEvents.Event.SYSTEM_INTERACTION);
20712                }
20713            }
20714        }
20715        app.reportedInteraction = isInteraction;
20716        if (!isInteraction) {
20717            app.interactionEventTime = 0;
20718        }
20719    }
20720
20721    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20722        if (proc.thread != null) {
20723            if (proc.baseProcessTracker != null) {
20724                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20725            }
20726        }
20727    }
20728
20729    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20730            ProcessRecord TOP_APP, boolean doingAll, long now) {
20731        if (app.thread == null) {
20732            return false;
20733        }
20734
20735        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20736
20737        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20738    }
20739
20740    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20741            boolean oomAdj) {
20742        if (isForeground != proc.foregroundServices) {
20743            proc.foregroundServices = isForeground;
20744            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20745                    proc.info.uid);
20746            if (isForeground) {
20747                if (curProcs == null) {
20748                    curProcs = new ArrayList<ProcessRecord>();
20749                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20750                }
20751                if (!curProcs.contains(proc)) {
20752                    curProcs.add(proc);
20753                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20754                            proc.info.packageName, proc.info.uid);
20755                }
20756            } else {
20757                if (curProcs != null) {
20758                    if (curProcs.remove(proc)) {
20759                        mBatteryStatsService.noteEvent(
20760                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20761                                proc.info.packageName, proc.info.uid);
20762                        if (curProcs.size() <= 0) {
20763                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20764                        }
20765                    }
20766                }
20767            }
20768            if (oomAdj) {
20769                updateOomAdjLocked();
20770            }
20771        }
20772    }
20773
20774    private final ActivityRecord resumedAppLocked() {
20775        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
20776        String pkg;
20777        int uid;
20778        if (act != null) {
20779            pkg = act.packageName;
20780            uid = act.info.applicationInfo.uid;
20781        } else {
20782            pkg = null;
20783            uid = -1;
20784        }
20785        // Has the UID or resumed package name changed?
20786        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20787                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20788            if (mCurResumedPackage != null) {
20789                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20790                        mCurResumedPackage, mCurResumedUid);
20791            }
20792            mCurResumedPackage = pkg;
20793            mCurResumedUid = uid;
20794            if (mCurResumedPackage != null) {
20795                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20796                        mCurResumedPackage, mCurResumedUid);
20797            }
20798        }
20799        return act;
20800    }
20801
20802    final boolean updateOomAdjLocked(ProcessRecord app) {
20803        final ActivityRecord TOP_ACT = resumedAppLocked();
20804        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20805        final boolean wasCached = app.cached;
20806
20807        mAdjSeq++;
20808
20809        // This is the desired cached adjusment we want to tell it to use.
20810        // If our app is currently cached, we know it, and that is it.  Otherwise,
20811        // we don't know it yet, and it needs to now be cached we will then
20812        // need to do a complete oom adj.
20813        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20814                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20815        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20816                SystemClock.uptimeMillis());
20817        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20818            // Changed to/from cached state, so apps after it in the LRU
20819            // list may also be changed.
20820            updateOomAdjLocked();
20821        }
20822        return success;
20823    }
20824
20825    final void updateOomAdjLocked() {
20826        final ActivityRecord TOP_ACT = resumedAppLocked();
20827        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20828        final long now = SystemClock.uptimeMillis();
20829        final long nowElapsed = SystemClock.elapsedRealtime();
20830        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20831        final int N = mLruProcesses.size();
20832
20833        if (false) {
20834            RuntimeException e = new RuntimeException();
20835            e.fillInStackTrace();
20836            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20837        }
20838
20839        // Reset state in all uid records.
20840        for (int i=mActiveUids.size()-1; i>=0; i--) {
20841            final UidRecord uidRec = mActiveUids.valueAt(i);
20842            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20843                    "Starting update of " + uidRec);
20844            uidRec.reset();
20845        }
20846
20847        mStackSupervisor.rankTaskLayersIfNeeded();
20848
20849        mAdjSeq++;
20850        mNewNumServiceProcs = 0;
20851        mNewNumAServiceProcs = 0;
20852
20853        final int emptyProcessLimit;
20854        final int cachedProcessLimit;
20855        if (mProcessLimit <= 0) {
20856            emptyProcessLimit = cachedProcessLimit = 0;
20857        } else if (mProcessLimit == 1) {
20858            emptyProcessLimit = 1;
20859            cachedProcessLimit = 0;
20860        } else {
20861            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20862            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20863        }
20864
20865        // Let's determine how many processes we have running vs.
20866        // how many slots we have for background processes; we may want
20867        // to put multiple processes in a slot of there are enough of
20868        // them.
20869        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20870                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20871        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20872        if (numEmptyProcs > cachedProcessLimit) {
20873            // If there are more empty processes than our limit on cached
20874            // processes, then use the cached process limit for the factor.
20875            // This ensures that the really old empty processes get pushed
20876            // down to the bottom, so if we are running low on memory we will
20877            // have a better chance at keeping around more cached processes
20878            // instead of a gazillion empty processes.
20879            numEmptyProcs = cachedProcessLimit;
20880        }
20881        int emptyFactor = numEmptyProcs/numSlots;
20882        if (emptyFactor < 1) emptyFactor = 1;
20883        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20884        if (cachedFactor < 1) cachedFactor = 1;
20885        int stepCached = 0;
20886        int stepEmpty = 0;
20887        int numCached = 0;
20888        int numEmpty = 0;
20889        int numTrimming = 0;
20890
20891        mNumNonCachedProcs = 0;
20892        mNumCachedHiddenProcs = 0;
20893
20894        // First update the OOM adjustment for each of the
20895        // application processes based on their current state.
20896        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20897        int nextCachedAdj = curCachedAdj+1;
20898        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20899        int nextEmptyAdj = curEmptyAdj+2;
20900        for (int i=N-1; i>=0; i--) {
20901            ProcessRecord app = mLruProcesses.get(i);
20902            if (!app.killedByAm && app.thread != null) {
20903                app.procStateChanged = false;
20904                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20905
20906                // If we haven't yet assigned the final cached adj
20907                // to the process, do that now.
20908                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20909                    switch (app.curProcState) {
20910                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20911                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20912                            // This process is a cached process holding activities...
20913                            // assign it the next cached value for that type, and then
20914                            // step that cached level.
20915                            app.curRawAdj = curCachedAdj;
20916                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20917                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20918                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20919                                    + ")");
20920                            if (curCachedAdj != nextCachedAdj) {
20921                                stepCached++;
20922                                if (stepCached >= cachedFactor) {
20923                                    stepCached = 0;
20924                                    curCachedAdj = nextCachedAdj;
20925                                    nextCachedAdj += 2;
20926                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20927                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20928                                    }
20929                                }
20930                            }
20931                            break;
20932                        default:
20933                            // For everything else, assign next empty cached process
20934                            // level and bump that up.  Note that this means that
20935                            // long-running services that have dropped down to the
20936                            // cached level will be treated as empty (since their process
20937                            // state is still as a service), which is what we want.
20938                            app.curRawAdj = curEmptyAdj;
20939                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20940                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20941                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20942                                    + ")");
20943                            if (curEmptyAdj != nextEmptyAdj) {
20944                                stepEmpty++;
20945                                if (stepEmpty >= emptyFactor) {
20946                                    stepEmpty = 0;
20947                                    curEmptyAdj = nextEmptyAdj;
20948                                    nextEmptyAdj += 2;
20949                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20950                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20951                                    }
20952                                }
20953                            }
20954                            break;
20955                    }
20956                }
20957
20958                applyOomAdjLocked(app, true, now, nowElapsed);
20959
20960                // Count the number of process types.
20961                switch (app.curProcState) {
20962                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20963                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20964                        mNumCachedHiddenProcs++;
20965                        numCached++;
20966                        if (numCached > cachedProcessLimit) {
20967                            app.kill("cached #" + numCached, true);
20968                        }
20969                        break;
20970                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20971                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20972                                && app.lastActivityTime < oldTime) {
20973                            app.kill("empty for "
20974                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20975                                    / 1000) + "s", true);
20976                        } else {
20977                            numEmpty++;
20978                            if (numEmpty > emptyProcessLimit) {
20979                                app.kill("empty #" + numEmpty, true);
20980                            }
20981                        }
20982                        break;
20983                    default:
20984                        mNumNonCachedProcs++;
20985                        break;
20986                }
20987
20988                if (app.isolated && app.services.size() <= 0) {
20989                    // If this is an isolated process, and there are no
20990                    // services running in it, then the process is no longer
20991                    // needed.  We agressively kill these because we can by
20992                    // definition not re-use the same process again, and it is
20993                    // good to avoid having whatever code was running in them
20994                    // left sitting around after no longer needed.
20995                    app.kill("isolated not needed", true);
20996                } else {
20997                    // Keeping this process, update its uid.
20998                    final UidRecord uidRec = app.uidRecord;
20999                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21000                        uidRec.curProcState = app.curProcState;
21001                    }
21002                }
21003
21004                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21005                        && !app.killedByAm) {
21006                    numTrimming++;
21007                }
21008            }
21009        }
21010
21011        mNumServiceProcs = mNewNumServiceProcs;
21012
21013        // Now determine the memory trimming level of background processes.
21014        // Unfortunately we need to start at the back of the list to do this
21015        // properly.  We only do this if the number of background apps we
21016        // are managing to keep around is less than half the maximum we desire;
21017        // if we are keeping a good number around, we'll let them use whatever
21018        // memory they want.
21019        final int numCachedAndEmpty = numCached + numEmpty;
21020        int memFactor;
21021        if (numCached <= ProcessList.TRIM_CACHED_APPS
21022                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21023            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21024                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21025            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21026                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21027            } else {
21028                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21029            }
21030        } else {
21031            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21032        }
21033        // We always allow the memory level to go up (better).  We only allow it to go
21034        // down if we are in a state where that is allowed, *and* the total number of processes
21035        // has gone down since last time.
21036        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21037                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21038                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21039        if (memFactor > mLastMemoryLevel) {
21040            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21041                memFactor = mLastMemoryLevel;
21042                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21043            }
21044        }
21045        if (memFactor != mLastMemoryLevel) {
21046            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21047        }
21048        mLastMemoryLevel = memFactor;
21049        mLastNumProcesses = mLruProcesses.size();
21050        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21051        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21052        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21053            if (mLowRamStartTime == 0) {
21054                mLowRamStartTime = now;
21055            }
21056            int step = 0;
21057            int fgTrimLevel;
21058            switch (memFactor) {
21059                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21060                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21061                    break;
21062                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21063                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21064                    break;
21065                default:
21066                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21067                    break;
21068            }
21069            int factor = numTrimming/3;
21070            int minFactor = 2;
21071            if (mHomeProcess != null) minFactor++;
21072            if (mPreviousProcess != null) minFactor++;
21073            if (factor < minFactor) factor = minFactor;
21074            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21075            for (int i=N-1; i>=0; i--) {
21076                ProcessRecord app = mLruProcesses.get(i);
21077                if (allChanged || app.procStateChanged) {
21078                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21079                    app.procStateChanged = false;
21080                }
21081                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21082                        && !app.killedByAm) {
21083                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21084                        try {
21085                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21086                                    "Trimming memory of " + app.processName + " to " + curLevel);
21087                            app.thread.scheduleTrimMemory(curLevel);
21088                        } catch (RemoteException e) {
21089                        }
21090                        if (false) {
21091                            // For now we won't do this; our memory trimming seems
21092                            // to be good enough at this point that destroying
21093                            // activities causes more harm than good.
21094                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21095                                    && app != mHomeProcess && app != mPreviousProcess) {
21096                                // Need to do this on its own message because the stack may not
21097                                // be in a consistent state at this point.
21098                                // For these apps we will also finish their activities
21099                                // to help them free memory.
21100                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21101                            }
21102                        }
21103                    }
21104                    app.trimMemoryLevel = curLevel;
21105                    step++;
21106                    if (step >= factor) {
21107                        step = 0;
21108                        switch (curLevel) {
21109                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21110                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21111                                break;
21112                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21113                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21114                                break;
21115                        }
21116                    }
21117                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21118                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21119                            && app.thread != null) {
21120                        try {
21121                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21122                                    "Trimming memory of heavy-weight " + app.processName
21123                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21124                            app.thread.scheduleTrimMemory(
21125                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21126                        } catch (RemoteException e) {
21127                        }
21128                    }
21129                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21130                } else {
21131                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21132                            || app.systemNoUi) && app.pendingUiClean) {
21133                        // If this application is now in the background and it
21134                        // had done UI, then give it the special trim level to
21135                        // have it free UI resources.
21136                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21137                        if (app.trimMemoryLevel < level && app.thread != null) {
21138                            try {
21139                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21140                                        "Trimming memory of bg-ui " + app.processName
21141                                        + " to " + level);
21142                                app.thread.scheduleTrimMemory(level);
21143                            } catch (RemoteException e) {
21144                            }
21145                        }
21146                        app.pendingUiClean = false;
21147                    }
21148                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21149                        try {
21150                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21151                                    "Trimming memory of fg " + app.processName
21152                                    + " to " + fgTrimLevel);
21153                            app.thread.scheduleTrimMemory(fgTrimLevel);
21154                        } catch (RemoteException e) {
21155                        }
21156                    }
21157                    app.trimMemoryLevel = fgTrimLevel;
21158                }
21159            }
21160        } else {
21161            if (mLowRamStartTime != 0) {
21162                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21163                mLowRamStartTime = 0;
21164            }
21165            for (int i=N-1; i>=0; i--) {
21166                ProcessRecord app = mLruProcesses.get(i);
21167                if (allChanged || app.procStateChanged) {
21168                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21169                    app.procStateChanged = false;
21170                }
21171                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21172                        || app.systemNoUi) && app.pendingUiClean) {
21173                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21174                            && app.thread != null) {
21175                        try {
21176                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21177                                    "Trimming memory of ui hidden " + app.processName
21178                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21179                            app.thread.scheduleTrimMemory(
21180                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21181                        } catch (RemoteException e) {
21182                        }
21183                    }
21184                    app.pendingUiClean = false;
21185                }
21186                app.trimMemoryLevel = 0;
21187            }
21188        }
21189
21190        if (mAlwaysFinishActivities) {
21191            // Need to do this on its own message because the stack may not
21192            // be in a consistent state at this point.
21193            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21194        }
21195
21196        if (allChanged) {
21197            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21198        }
21199
21200        // Update from any uid changes.
21201        if (mLocalPowerManager != null) {
21202            mLocalPowerManager.startUidChanges();
21203        }
21204        for (int i=mActiveUids.size()-1; i>=0; i--) {
21205            final UidRecord uidRec = mActiveUids.valueAt(i);
21206            int uidChange = UidRecord.CHANGE_PROCSTATE;
21207            if (uidRec.setProcState != uidRec.curProcState) {
21208                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21209                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21210                        + " to " + uidRec.curProcState);
21211                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21212                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21213                        uidRec.lastBackgroundTime = nowElapsed;
21214                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21215                            // Note: the background settle time is in elapsed realtime, while
21216                            // the handler time base is uptime.  All this means is that we may
21217                            // stop background uids later than we had intended, but that only
21218                            // happens because the device was sleeping so we are okay anyway.
21219                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21220                        }
21221                    }
21222                } else {
21223                    if (uidRec.idle) {
21224                        uidChange = UidRecord.CHANGE_ACTIVE;
21225                        uidRec.idle = false;
21226                    }
21227                    uidRec.lastBackgroundTime = 0;
21228                }
21229                uidRec.setProcState = uidRec.curProcState;
21230                enqueueUidChangeLocked(uidRec, -1, uidChange);
21231                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21232            }
21233        }
21234        if (mLocalPowerManager != null) {
21235            mLocalPowerManager.finishUidChanges();
21236        }
21237
21238        if (mProcessStats.shouldWriteNowLocked(now)) {
21239            mHandler.post(new Runnable() {
21240                @Override public void run() {
21241                    synchronized (ActivityManagerService.this) {
21242                        mProcessStats.writeStateAsyncLocked();
21243                    }
21244                }
21245            });
21246        }
21247
21248        if (DEBUG_OOM_ADJ) {
21249            final long duration = SystemClock.uptimeMillis() - now;
21250            if (false) {
21251                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21252                        new RuntimeException("here").fillInStackTrace());
21253            } else {
21254                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21255            }
21256        }
21257    }
21258
21259    final void idleUids() {
21260        synchronized (this) {
21261            final int N = mActiveUids.size();
21262            if (N <= 0) {
21263                return;
21264            }
21265            final long nowElapsed = SystemClock.elapsedRealtime();
21266            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21267            long nextTime = 0;
21268            if (mLocalPowerManager != null) {
21269                mLocalPowerManager.startUidChanges();
21270            }
21271            for (int i=N-1; i>=0; i--) {
21272                final UidRecord uidRec = mActiveUids.valueAt(i);
21273                final long bgTime = uidRec.lastBackgroundTime;
21274                if (bgTime > 0 && !uidRec.idle) {
21275                    if (bgTime <= maxBgTime) {
21276                        uidRec.idle = true;
21277                        doStopUidLocked(uidRec.uid, uidRec);
21278                    } else {
21279                        if (nextTime == 0 || nextTime > bgTime) {
21280                            nextTime = bgTime;
21281                        }
21282                    }
21283                }
21284            }
21285            if (mLocalPowerManager != null) {
21286                mLocalPowerManager.finishUidChanges();
21287            }
21288            if (nextTime > 0) {
21289                mHandler.removeMessages(IDLE_UIDS_MSG);
21290                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21291                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21292            }
21293        }
21294    }
21295
21296    final void runInBackgroundDisabled(int uid) {
21297        synchronized (this) {
21298            UidRecord uidRec = mActiveUids.get(uid);
21299            if (uidRec != null) {
21300                // This uid is actually running...  should it be considered background now?
21301                if (uidRec.idle) {
21302                    doStopUidLocked(uidRec.uid, uidRec);
21303                }
21304            } else {
21305                // This uid isn't actually running...  still send a report about it being "stopped".
21306                doStopUidLocked(uid, null);
21307            }
21308        }
21309    }
21310
21311    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21312        mServices.stopInBackgroundLocked(uid);
21313        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21314    }
21315
21316    final void trimApplications() {
21317        synchronized (this) {
21318            int i;
21319
21320            // First remove any unused application processes whose package
21321            // has been removed.
21322            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21323                final ProcessRecord app = mRemovedProcesses.get(i);
21324                if (app.activities.size() == 0
21325                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21326                    Slog.i(
21327                        TAG, "Exiting empty application process "
21328                        + app.toShortString() + " ("
21329                        + (app.thread != null ? app.thread.asBinder() : null)
21330                        + ")\n");
21331                    if (app.pid > 0 && app.pid != MY_PID) {
21332                        app.kill("empty", false);
21333                    } else {
21334                        try {
21335                            app.thread.scheduleExit();
21336                        } catch (Exception e) {
21337                            // Ignore exceptions.
21338                        }
21339                    }
21340                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21341                    mRemovedProcesses.remove(i);
21342
21343                    if (app.persistent) {
21344                        addAppLocked(app.info, false, null /* ABI override */);
21345                    }
21346                }
21347            }
21348
21349            // Now update the oom adj for all processes.
21350            updateOomAdjLocked();
21351        }
21352    }
21353
21354    /** This method sends the specified signal to each of the persistent apps */
21355    public void signalPersistentProcesses(int sig) throws RemoteException {
21356        if (sig != Process.SIGNAL_USR1) {
21357            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21358        }
21359
21360        synchronized (this) {
21361            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21362                    != PackageManager.PERMISSION_GRANTED) {
21363                throw new SecurityException("Requires permission "
21364                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21365            }
21366
21367            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21368                ProcessRecord r = mLruProcesses.get(i);
21369                if (r.thread != null && r.persistent) {
21370                    Process.sendSignal(r.pid, sig);
21371                }
21372            }
21373        }
21374    }
21375
21376    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21377        if (proc == null || proc == mProfileProc) {
21378            proc = mProfileProc;
21379            profileType = mProfileType;
21380            clearProfilerLocked();
21381        }
21382        if (proc == null) {
21383            return;
21384        }
21385        try {
21386            proc.thread.profilerControl(false, null, profileType);
21387        } catch (RemoteException e) {
21388            throw new IllegalStateException("Process disappeared");
21389        }
21390    }
21391
21392    private void clearProfilerLocked() {
21393        if (mProfileFd != null) {
21394            try {
21395                mProfileFd.close();
21396            } catch (IOException e) {
21397            }
21398        }
21399        mProfileApp = null;
21400        mProfileProc = null;
21401        mProfileFile = null;
21402        mProfileType = 0;
21403        mAutoStopProfiler = false;
21404        mSamplingInterval = 0;
21405    }
21406
21407    public boolean profileControl(String process, int userId, boolean start,
21408            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21409
21410        try {
21411            synchronized (this) {
21412                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21413                // its own permission.
21414                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21415                        != PackageManager.PERMISSION_GRANTED) {
21416                    throw new SecurityException("Requires permission "
21417                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21418                }
21419
21420                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21421                    throw new IllegalArgumentException("null profile info or fd");
21422                }
21423
21424                ProcessRecord proc = null;
21425                if (process != null) {
21426                    proc = findProcessLocked(process, userId, "profileControl");
21427                }
21428
21429                if (start && (proc == null || proc.thread == null)) {
21430                    throw new IllegalArgumentException("Unknown process: " + process);
21431                }
21432
21433                if (start) {
21434                    stopProfilerLocked(null, 0);
21435                    setProfileApp(proc.info, proc.processName, profilerInfo);
21436                    mProfileProc = proc;
21437                    mProfileType = profileType;
21438                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21439                    try {
21440                        fd = fd.dup();
21441                    } catch (IOException e) {
21442                        fd = null;
21443                    }
21444                    profilerInfo.profileFd = fd;
21445                    proc.thread.profilerControl(start, profilerInfo, profileType);
21446                    fd = null;
21447                    mProfileFd = null;
21448                } else {
21449                    stopProfilerLocked(proc, profileType);
21450                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21451                        try {
21452                            profilerInfo.profileFd.close();
21453                        } catch (IOException e) {
21454                        }
21455                    }
21456                }
21457
21458                return true;
21459            }
21460        } catch (RemoteException e) {
21461            throw new IllegalStateException("Process disappeared");
21462        } finally {
21463            if (profilerInfo != null && profilerInfo.profileFd != null) {
21464                try {
21465                    profilerInfo.profileFd.close();
21466                } catch (IOException e) {
21467                }
21468            }
21469        }
21470    }
21471
21472    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21473        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21474                userId, true, ALLOW_FULL_ONLY, callName, null);
21475        ProcessRecord proc = null;
21476        try {
21477            int pid = Integer.parseInt(process);
21478            synchronized (mPidsSelfLocked) {
21479                proc = mPidsSelfLocked.get(pid);
21480            }
21481        } catch (NumberFormatException e) {
21482        }
21483
21484        if (proc == null) {
21485            ArrayMap<String, SparseArray<ProcessRecord>> all
21486                    = mProcessNames.getMap();
21487            SparseArray<ProcessRecord> procs = all.get(process);
21488            if (procs != null && procs.size() > 0) {
21489                proc = procs.valueAt(0);
21490                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21491                    for (int i=1; i<procs.size(); i++) {
21492                        ProcessRecord thisProc = procs.valueAt(i);
21493                        if (thisProc.userId == userId) {
21494                            proc = thisProc;
21495                            break;
21496                        }
21497                    }
21498                }
21499            }
21500        }
21501
21502        return proc;
21503    }
21504
21505    public boolean dumpHeap(String process, int userId, boolean managed,
21506            String path, ParcelFileDescriptor fd) throws RemoteException {
21507
21508        try {
21509            synchronized (this) {
21510                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21511                // its own permission (same as profileControl).
21512                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21513                        != PackageManager.PERMISSION_GRANTED) {
21514                    throw new SecurityException("Requires permission "
21515                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21516                }
21517
21518                if (fd == null) {
21519                    throw new IllegalArgumentException("null fd");
21520                }
21521
21522                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21523                if (proc == null || proc.thread == null) {
21524                    throw new IllegalArgumentException("Unknown process: " + process);
21525                }
21526
21527                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21528                if (!isDebuggable) {
21529                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21530                        throw new SecurityException("Process not debuggable: " + proc);
21531                    }
21532                }
21533
21534                proc.thread.dumpHeap(managed, path, fd);
21535                fd = null;
21536                return true;
21537            }
21538        } catch (RemoteException e) {
21539            throw new IllegalStateException("Process disappeared");
21540        } finally {
21541            if (fd != null) {
21542                try {
21543                    fd.close();
21544                } catch (IOException e) {
21545                }
21546            }
21547        }
21548    }
21549
21550    @Override
21551    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21552            String reportPackage) {
21553        if (processName != null) {
21554            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21555                    "setDumpHeapDebugLimit()");
21556        } else {
21557            synchronized (mPidsSelfLocked) {
21558                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21559                if (proc == null) {
21560                    throw new SecurityException("No process found for calling pid "
21561                            + Binder.getCallingPid());
21562                }
21563                if (!Build.IS_DEBUGGABLE
21564                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21565                    throw new SecurityException("Not running a debuggable build");
21566                }
21567                processName = proc.processName;
21568                uid = proc.uid;
21569                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21570                    throw new SecurityException("Package " + reportPackage + " is not running in "
21571                            + proc);
21572                }
21573            }
21574        }
21575        synchronized (this) {
21576            if (maxMemSize > 0) {
21577                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21578            } else {
21579                if (uid != 0) {
21580                    mMemWatchProcesses.remove(processName, uid);
21581                } else {
21582                    mMemWatchProcesses.getMap().remove(processName);
21583                }
21584            }
21585        }
21586    }
21587
21588    @Override
21589    public void dumpHeapFinished(String path) {
21590        synchronized (this) {
21591            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21592                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21593                        + " does not match last pid " + mMemWatchDumpPid);
21594                return;
21595            }
21596            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21597                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21598                        + " does not match last path " + mMemWatchDumpFile);
21599                return;
21600            }
21601            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21602            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21603        }
21604    }
21605
21606    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21607    public void monitor() {
21608        synchronized (this) { }
21609    }
21610
21611    void onCoreSettingsChange(Bundle settings) {
21612        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21613            ProcessRecord processRecord = mLruProcesses.get(i);
21614            try {
21615                if (processRecord.thread != null) {
21616                    processRecord.thread.setCoreSettings(settings);
21617                }
21618            } catch (RemoteException re) {
21619                /* ignore */
21620            }
21621        }
21622    }
21623
21624    // Multi-user methods
21625
21626    /**
21627     * Start user, if its not already running, but don't bring it to foreground.
21628     */
21629    @Override
21630    public boolean startUserInBackground(final int userId) {
21631        return mUserController.startUser(userId, /* foreground */ false);
21632    }
21633
21634    @Override
21635    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21636        return mUserController.unlockUser(userId, token, secret, listener);
21637    }
21638
21639    @Override
21640    public boolean switchUser(final int targetUserId) {
21641        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21642        int currentUserId;
21643        UserInfo targetUserInfo;
21644        synchronized (this) {
21645            currentUserId = mUserController.getCurrentUserIdLocked();
21646            targetUserInfo = mUserController.getUserInfo(targetUserId);
21647            if (targetUserId == currentUserId) {
21648                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
21649                return true;
21650            }
21651            if (targetUserInfo == null) {
21652                Slog.w(TAG, "No user info for user #" + targetUserId);
21653                return false;
21654            }
21655            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21656                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21657                        + " when device is in demo mode");
21658                return false;
21659            }
21660            if (!targetUserInfo.supportsSwitchTo()) {
21661                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21662                return false;
21663            }
21664            if (targetUserInfo.isManagedProfile()) {
21665                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21666                return false;
21667            }
21668            mUserController.setTargetUserIdLocked(targetUserId);
21669        }
21670        if (mUserController.mUserSwitchUiEnabled) {
21671            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
21672            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21673            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21674            mUiHandler.sendMessage(mHandler.obtainMessage(
21675                    START_USER_SWITCH_UI_MSG, userNames));
21676        } else {
21677            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
21678            mHandler.sendMessage(mHandler.obtainMessage(
21679                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
21680        }
21681        return true;
21682    }
21683
21684    void scheduleStartProfilesLocked() {
21685        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21686            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21687                    DateUtils.SECOND_IN_MILLIS);
21688        }
21689    }
21690
21691    @Override
21692    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21693        return mUserController.stopUser(userId, force, callback);
21694    }
21695
21696    @Override
21697    public UserInfo getCurrentUser() {
21698        return mUserController.getCurrentUser();
21699    }
21700
21701    String getStartedUserState(int userId) {
21702        synchronized (this) {
21703            final UserState userState = mUserController.getStartedUserStateLocked(userId);
21704            return UserState.stateToString(userState.state);
21705        }
21706    }
21707
21708    @Override
21709    public boolean isUserRunning(int userId, int flags) {
21710        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21711                && checkCallingPermission(INTERACT_ACROSS_USERS)
21712                    != PackageManager.PERMISSION_GRANTED) {
21713            String msg = "Permission Denial: isUserRunning() from pid="
21714                    + Binder.getCallingPid()
21715                    + ", uid=" + Binder.getCallingUid()
21716                    + " requires " + INTERACT_ACROSS_USERS;
21717            Slog.w(TAG, msg);
21718            throw new SecurityException(msg);
21719        }
21720        synchronized (this) {
21721            return mUserController.isUserRunningLocked(userId, flags);
21722        }
21723    }
21724
21725    @Override
21726    public int[] getRunningUserIds() {
21727        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21728                != PackageManager.PERMISSION_GRANTED) {
21729            String msg = "Permission Denial: isUserRunning() from pid="
21730                    + Binder.getCallingPid()
21731                    + ", uid=" + Binder.getCallingUid()
21732                    + " requires " + INTERACT_ACROSS_USERS;
21733            Slog.w(TAG, msg);
21734            throw new SecurityException(msg);
21735        }
21736        synchronized (this) {
21737            return mUserController.getStartedUserArrayLocked();
21738        }
21739    }
21740
21741    @Override
21742    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21743        mUserController.registerUserSwitchObserver(observer, name);
21744    }
21745
21746    @Override
21747    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21748        mUserController.unregisterUserSwitchObserver(observer);
21749    }
21750
21751    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21752        if (info == null) return null;
21753        ApplicationInfo newInfo = new ApplicationInfo(info);
21754        newInfo.initForUser(userId);
21755        return newInfo;
21756    }
21757
21758    public boolean isUserStopped(int userId) {
21759        synchronized (this) {
21760            return mUserController.getStartedUserStateLocked(userId) == null;
21761        }
21762    }
21763
21764    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21765        if (aInfo == null
21766                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21767            return aInfo;
21768        }
21769
21770        ActivityInfo info = new ActivityInfo(aInfo);
21771        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21772        return info;
21773    }
21774
21775    private boolean processSanityChecksLocked(ProcessRecord process) {
21776        if (process == null || process.thread == null) {
21777            return false;
21778        }
21779
21780        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21781        if (!isDebuggable) {
21782            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21783                return false;
21784            }
21785        }
21786
21787        return true;
21788    }
21789
21790    public boolean startBinderTracking() throws RemoteException {
21791        synchronized (this) {
21792            mBinderTransactionTrackingEnabled = true;
21793            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21794            // permission (same as profileControl).
21795            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21796                    != PackageManager.PERMISSION_GRANTED) {
21797                throw new SecurityException("Requires permission "
21798                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21799            }
21800
21801            for (int i = 0; i < mLruProcesses.size(); i++) {
21802                ProcessRecord process = mLruProcesses.get(i);
21803                if (!processSanityChecksLocked(process)) {
21804                    continue;
21805                }
21806                try {
21807                    process.thread.startBinderTracking();
21808                } catch (RemoteException e) {
21809                    Log.v(TAG, "Process disappared");
21810                }
21811            }
21812            return true;
21813        }
21814    }
21815
21816    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21817        try {
21818            synchronized (this) {
21819                mBinderTransactionTrackingEnabled = false;
21820                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21821                // permission (same as profileControl).
21822                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21823                        != PackageManager.PERMISSION_GRANTED) {
21824                    throw new SecurityException("Requires permission "
21825                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21826                }
21827
21828                if (fd == null) {
21829                    throw new IllegalArgumentException("null fd");
21830                }
21831
21832                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21833                pw.println("Binder transaction traces for all processes.\n");
21834                for (ProcessRecord process : mLruProcesses) {
21835                    if (!processSanityChecksLocked(process)) {
21836                        continue;
21837                    }
21838
21839                    pw.println("Traces for process: " + process.processName);
21840                    pw.flush();
21841                    try {
21842                        TransferPipe tp = new TransferPipe();
21843                        try {
21844                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
21845                            tp.go(fd.getFileDescriptor());
21846                        } finally {
21847                            tp.kill();
21848                        }
21849                    } catch (IOException e) {
21850                        pw.println("Failure while dumping IPC traces from " + process +
21851                                ".  Exception: " + e);
21852                        pw.flush();
21853                    } catch (RemoteException e) {
21854                        pw.println("Got a RemoteException while dumping IPC traces from " +
21855                                process + ".  Exception: " + e);
21856                        pw.flush();
21857                    }
21858                }
21859                fd = null;
21860                return true;
21861            }
21862        } finally {
21863            if (fd != null) {
21864                try {
21865                    fd.close();
21866                } catch (IOException e) {
21867                }
21868            }
21869        }
21870    }
21871
21872    private final class LocalService extends ActivityManagerInternal {
21873        @Override
21874        public void onWakefulnessChanged(int wakefulness) {
21875            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21876        }
21877
21878        @Override
21879        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21880                String processName, String abiOverride, int uid, Runnable crashHandler) {
21881            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21882                    processName, abiOverride, uid, crashHandler);
21883        }
21884
21885        @Override
21886        public SleepToken acquireSleepToken(String tag) {
21887            Preconditions.checkNotNull(tag);
21888
21889            ComponentName requestedVrService = null;
21890            ComponentName callingVrActivity = null;
21891            int userId = -1;
21892            synchronized (ActivityManagerService.this) {
21893                final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
21894                if (resumedActivity != null) {
21895                    requestedVrService = resumedActivity.requestedVrComponent;
21896                    callingVrActivity = resumedActivity.info.getComponentName();
21897                    userId = resumedActivity.userId;
21898                }
21899            }
21900
21901            if (requestedVrService != null) {
21902                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21903            }
21904
21905            synchronized (ActivityManagerService.this) {
21906                SleepTokenImpl token = new SleepTokenImpl(tag);
21907                mSleepTokens.add(token);
21908                updateSleepIfNeededLocked();
21909                return token;
21910            }
21911        }
21912
21913        @Override
21914        public ComponentName getHomeActivityForUser(int userId) {
21915            synchronized (ActivityManagerService.this) {
21916                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21917                return homeActivity == null ? null : homeActivity.realActivity;
21918            }
21919        }
21920
21921        @Override
21922        public void onUserRemoved(int userId) {
21923            synchronized (ActivityManagerService.this) {
21924                ActivityManagerService.this.onUserStoppedLocked(userId);
21925            }
21926        }
21927
21928        @Override
21929        public void onLocalVoiceInteractionStarted(IBinder activity,
21930                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21931            synchronized (ActivityManagerService.this) {
21932                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21933                        voiceSession, voiceInteractor);
21934            }
21935        }
21936
21937        @Override
21938        public void notifyStartingWindowDrawn() {
21939            synchronized (ActivityManagerService.this) {
21940                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21941            }
21942        }
21943
21944        @Override
21945        public void notifyAppTransitionStarting(int reason) {
21946            synchronized (ActivityManagerService.this) {
21947                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21948            }
21949        }
21950
21951        @Override
21952        public void notifyAppTransitionFinished() {
21953            synchronized (ActivityManagerService.this) {
21954                mStackSupervisor.notifyAppTransitionDone();
21955            }
21956        }
21957
21958        @Override
21959        public void notifyAppTransitionCancelled() {
21960            synchronized (ActivityManagerService.this) {
21961                mStackSupervisor.notifyAppTransitionDone();
21962            }
21963        }
21964
21965        @Override
21966        public List<IBinder> getTopVisibleActivities() {
21967            synchronized (ActivityManagerService.this) {
21968                return mStackSupervisor.getTopVisibleActivities();
21969            }
21970        }
21971
21972        @Override
21973        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21974            synchronized (ActivityManagerService.this) {
21975                mStackSupervisor.setDockedStackMinimized(minimized);
21976            }
21977        }
21978
21979        @Override
21980        public void killForegroundAppsForUser(int userHandle) {
21981            synchronized (ActivityManagerService.this) {
21982                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21983                final int NP = mProcessNames.getMap().size();
21984                for (int ip = 0; ip < NP; ip++) {
21985                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21986                    final int NA = apps.size();
21987                    for (int ia = 0; ia < NA; ia++) {
21988                        final ProcessRecord app = apps.valueAt(ia);
21989                        if (app.persistent) {
21990                            // We don't kill persistent processes.
21991                            continue;
21992                        }
21993                        if (app.removed) {
21994                            procs.add(app);
21995                        } else if (app.userId == userHandle && app.foregroundActivities) {
21996                            app.removed = true;
21997                            procs.add(app);
21998                        }
21999                    }
22000                }
22001
22002                final int N = procs.size();
22003                for (int i = 0; i < N; i++) {
22004                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22005                }
22006            }
22007        }
22008
22009        @Override
22010        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22011            if (!(target instanceof PendingIntentRecord)) {
22012                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22013                return;
22014            }
22015            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22016        }
22017
22018        @Override
22019        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22020                int userId) {
22021            Preconditions.checkNotNull(values, "Configuration must not be null");
22022            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22023            synchronized (ActivityManagerService.this) {
22024                updateConfigurationLocked(values, null, false, true, userId,
22025                        false /* deferResume */);
22026            }
22027        }
22028
22029        @Override
22030        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22031                Bundle bOptions) {
22032            Preconditions.checkNotNull(intents, "intents");
22033            final String[] resolvedTypes = new String[intents.length];
22034            for (int i = 0; i < intents.length; i++) {
22035                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22036            }
22037
22038            // UID of the package on user userId.
22039            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22040            // packageUid may not be initialized.
22041            int packageUid = 0;
22042            try {
22043                packageUid = AppGlobals.getPackageManager().getPackageUid(
22044                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22045            } catch (RemoteException e) {
22046                // Shouldn't happen.
22047            }
22048
22049            synchronized (ActivityManagerService.this) {
22050                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22051                        /*resultTo*/ null, bOptions, userId);
22052            }
22053        }
22054
22055        @Override
22056        public int getUidProcessState(int uid) {
22057            return getUidState(uid);
22058        }
22059
22060        @Override
22061        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
22062            synchronized (ActivityManagerService.this) {
22063
22064                // We might change the visibilities here, so prepare an empty app transition which
22065                // might be overridden later if we actually change visibilities.
22066                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
22067                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22068                mWindowManager.executeAppTransition();
22069            }
22070            if (callback != null) {
22071                callback.run();
22072            }
22073        }
22074
22075        @Override
22076        public boolean isSystemReady() {
22077            // no need to synchronize(this) just to read & return the value
22078            return mSystemReady;
22079        }
22080
22081        @Override
22082        public void notifyKeyguardTrustedChanged() {
22083            synchronized (ActivityManagerService.this) {
22084                if (mKeyguardController.isKeyguardShowing()) {
22085                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22086                }
22087            }
22088        }
22089    }
22090
22091    private final class SleepTokenImpl extends SleepToken {
22092        private final String mTag;
22093        private final long mAcquireTime;
22094
22095        public SleepTokenImpl(String tag) {
22096            mTag = tag;
22097            mAcquireTime = SystemClock.uptimeMillis();
22098        }
22099
22100        @Override
22101        public void release() {
22102            synchronized (ActivityManagerService.this) {
22103                if (mSleepTokens.remove(this)) {
22104                    updateSleepIfNeededLocked();
22105                }
22106            }
22107        }
22108
22109        @Override
22110        public String toString() {
22111            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22112        }
22113    }
22114
22115    /**
22116     * An implementation of IAppTask, that allows an app to manage its own tasks via
22117     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22118     * only the process that calls getAppTasks() can call the AppTask methods.
22119     */
22120    class AppTaskImpl extends IAppTask.Stub {
22121        private int mTaskId;
22122        private int mCallingUid;
22123
22124        public AppTaskImpl(int taskId, int callingUid) {
22125            mTaskId = taskId;
22126            mCallingUid = callingUid;
22127        }
22128
22129        private void checkCaller() {
22130            if (mCallingUid != Binder.getCallingUid()) {
22131                throw new SecurityException("Caller " + mCallingUid
22132                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22133            }
22134        }
22135
22136        @Override
22137        public void finishAndRemoveTask() {
22138            checkCaller();
22139
22140            synchronized (ActivityManagerService.this) {
22141                long origId = Binder.clearCallingIdentity();
22142                try {
22143                    // We remove the task from recents to preserve backwards
22144                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22145                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22146                    }
22147                } finally {
22148                    Binder.restoreCallingIdentity(origId);
22149                }
22150            }
22151        }
22152
22153        @Override
22154        public ActivityManager.RecentTaskInfo getTaskInfo() {
22155            checkCaller();
22156
22157            synchronized (ActivityManagerService.this) {
22158                long origId = Binder.clearCallingIdentity();
22159                try {
22160                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22161                    if (tr == null) {
22162                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22163                    }
22164                    return createRecentTaskInfoFromTaskRecord(tr);
22165                } finally {
22166                    Binder.restoreCallingIdentity(origId);
22167                }
22168            }
22169        }
22170
22171        @Override
22172        public void moveToFront() {
22173            checkCaller();
22174            // Will bring task to front if it already has a root activity.
22175            final long origId = Binder.clearCallingIdentity();
22176            try {
22177                synchronized (this) {
22178                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22179                }
22180            } finally {
22181                Binder.restoreCallingIdentity(origId);
22182            }
22183        }
22184
22185        @Override
22186        public int startActivity(IBinder whoThread, String callingPackage,
22187                Intent intent, String resolvedType, Bundle bOptions) {
22188            checkCaller();
22189
22190            int callingUser = UserHandle.getCallingUserId();
22191            TaskRecord tr;
22192            IApplicationThread appThread;
22193            synchronized (ActivityManagerService.this) {
22194                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22195                if (tr == null) {
22196                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22197                }
22198                appThread = IApplicationThread.Stub.asInterface(whoThread);
22199                if (appThread == null) {
22200                    throw new IllegalArgumentException("Bad app thread " + appThread);
22201                }
22202            }
22203            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22204                    resolvedType, null, null, null, null, 0, 0, null, null,
22205                    null, bOptions, false, callingUser, null, tr);
22206        }
22207
22208        @Override
22209        public void setExcludeFromRecents(boolean exclude) {
22210            checkCaller();
22211
22212            synchronized (ActivityManagerService.this) {
22213                long origId = Binder.clearCallingIdentity();
22214                try {
22215                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22216                    if (tr == null) {
22217                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22218                    }
22219                    Intent intent = tr.getBaseIntent();
22220                    if (exclude) {
22221                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22222                    } else {
22223                        intent.setFlags(intent.getFlags()
22224                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22225                    }
22226                } finally {
22227                    Binder.restoreCallingIdentity(origId);
22228                }
22229            }
22230        }
22231    }
22232
22233    /**
22234     * Kill processes for the user with id userId and that depend on the package named packageName
22235     */
22236    @Override
22237    public void killPackageDependents(String packageName, int userId) {
22238        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22239        if (packageName == null) {
22240            throw new NullPointerException(
22241                    "Cannot kill the dependents of a package without its name.");
22242        }
22243
22244        long callingId = Binder.clearCallingIdentity();
22245        IPackageManager pm = AppGlobals.getPackageManager();
22246        int pkgUid = -1;
22247        try {
22248            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22249        } catch (RemoteException e) {
22250        }
22251        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22252            throw new IllegalArgumentException(
22253                    "Cannot kill dependents of non-existing package " + packageName);
22254        }
22255        try {
22256            synchronized(this) {
22257                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22258                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22259                        "dep: " + packageName);
22260            }
22261        } finally {
22262            Binder.restoreCallingIdentity(callingId);
22263        }
22264    }
22265
22266    @Override
22267    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22268        final int userId = intent.getCreatorUserHandle().getIdentifier();
22269        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22270            return false;
22271        }
22272        IIntentSender target = intent.getTarget();
22273        if (!(target instanceof PendingIntentRecord)) {
22274            return false;
22275        }
22276        final PendingIntentRecord record = (PendingIntentRecord) target;
22277        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22278                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22279        // For direct boot aware activities, they can be shown without triggering a work challenge
22280        // before the profile user is unlocked.
22281        return rInfo != null && rInfo.activityInfo != null;
22282    }
22283
22284    /**
22285     * Attach an agent to the specified process (proces name or PID)
22286     */
22287    public void attachAgent(String process, String path) {
22288        try {
22289            synchronized (this) {
22290                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22291                if (proc == null || proc.thread == null) {
22292                    throw new IllegalArgumentException("Unknown process: " + process);
22293                }
22294
22295                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22296                if (!isDebuggable) {
22297                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22298                        throw new SecurityException("Process not debuggable: " + proc);
22299                    }
22300                }
22301
22302                proc.thread.attachAgent(path);
22303            }
22304        } catch (RemoteException e) {
22305            throw new IllegalStateException("Process disappeared");
22306        }
22307    }
22308}
22309