ActivityManagerService.java revision 585d8b28f5d174d0f50d0c7c3e5e7202f6cd36a1
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.internal.util.ProgressReporter;
45import com.android.server.AppOpsService;
46import com.android.server.AttributeCache;
47import com.android.server.DeviceIdleController;
48import com.android.server.IntentResolver;
49import com.android.server.LocalServices;
50import com.android.server.LockGuard;
51import com.android.server.ServiceThread;
52import com.android.server.SystemService;
53import com.android.server.SystemServiceManager;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.Installer;
58import com.android.server.statusbar.StatusBarManagerInternal;
59import com.android.server.vr.VrManagerInternal;
60import com.android.server.wm.WindowManagerService;
61
62import org.xmlpull.v1.XmlPullParser;
63import org.xmlpull.v1.XmlPullParserException;
64import org.xmlpull.v1.XmlSerializer;
65
66import android.Manifest;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.KeyguardManager;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.admin.DevicePolicyManagerInternal;
108import android.app.assist.AssistContent;
109import android.app.assist.AssistStructure;
110import android.app.backup.IBackupManager;
111import android.app.usage.UsageEvents;
112import android.app.usage.UsageStatsManagerInternal;
113import android.appwidget.AppWidgetManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.ParceledListSlice;
140import android.content.pm.PathPermission;
141import android.content.pm.PermissionInfo;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.pm.ShortcutServiceInternal;
146import android.content.pm.UserInfo;
147import android.content.res.CompatibilityInfo;
148import android.content.res.Configuration;
149import android.content.res.Resources;
150import android.database.ContentObserver;
151import android.graphics.Bitmap;
152import android.graphics.Point;
153import android.graphics.Rect;
154import android.location.LocationManager;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.BatteryStats;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IProcessInfoService;
172import android.os.IProgressListener;
173import android.os.LocaleList;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PersistableBundle;
179import android.os.PowerManager;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.ResultReceiver;
185import android.os.ServiceManager;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.Trace;
190import android.os.TransactionTooLargeException;
191import android.os.UpdateLock;
192import android.os.UserHandle;
193import android.os.UserManager;
194import android.os.WorkSource;
195import android.os.storage.IMountService;
196import android.os.storage.MountServiceInternal;
197import android.os.storage.StorageManager;
198import android.provider.Settings;
199import android.service.voice.IVoiceInteractionSession;
200import android.service.voice.VoiceInteractionManagerInternal;
201import android.service.voice.VoiceInteractionSession;
202import android.text.format.DateUtils;
203import android.text.format.Time;
204import android.text.style.SuggestionSpan;
205import android.util.ArrayMap;
206import android.util.ArraySet;
207import android.util.AtomicFile;
208import android.util.DebugUtils;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
267import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
268import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
269import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270import static android.content.pm.PackageManager.GET_PROVIDERS;
271import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
278import static android.provider.Settings.Global.DEBUG_APP;
279import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
281import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
282import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
283import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
284import static android.provider.Settings.System.FONT_SCALE;
285import static com.android.internal.util.XmlUtils.readBooleanAttribute;
286import static com.android.internal.util.XmlUtils.readIntAttribute;
287import static com.android.internal.util.XmlUtils.readLongAttribute;
288import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
289import static com.android.internal.util.XmlUtils.writeIntAttribute;
290import static com.android.internal.util.XmlUtils.writeLongAttribute;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastQueue broadcastQueueForIntent(Intent intent) {
571        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
572        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
573                "Broadcast intent " + intent + " on "
574                + (isFg ? "foreground" : "background") + " queue");
575        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
576    }
577
578    /**
579     * Activity we have told the window manager to have key focus.
580     */
581    ActivityRecord mFocusedActivity = null;
582
583    /**
584     * User id of the last activity mFocusedActivity was set to.
585     */
586    private int mLastFocusedUserId;
587
588    /**
589     * If non-null, we are tracking the time the user spends in the currently focused app.
590     */
591    private AppTimeTracker mCurAppTimeTracker;
592
593    /**
594     * List of intents that were used to start the most recent tasks.
595     */
596    final RecentTasks mRecentTasks;
597
598    /**
599     * For addAppTask: cached of the last activity component that was added.
600     */
601    ComponentName mLastAddedTaskComponent;
602
603    /**
604     * For addAppTask: cached of the last activity uid that was added.
605     */
606    int mLastAddedTaskUid;
607
608    /**
609     * For addAppTask: cached of the last ActivityInfo that was added.
610     */
611    ActivityInfo mLastAddedTaskActivity;
612
613    /**
614     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
615     */
616    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
617
618    /**
619     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
620     */
621    String mDeviceOwnerName;
622
623    final UserController mUserController;
624
625    final AppErrors mAppErrors;
626
627    boolean mDoingSetFocusedActivity;
628
629    public boolean canShowErrorDialogs() {
630        return mShowDialogs && !mSleeping && !mShuttingDown;
631    }
632
633    // it's a semaphore; boost when 0->1, reset when 1->0
634    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
635        @Override protected Integer initialValue() {
636            return 0;
637        }
638    };
639
640    static void boostPriorityForLockedSection() {
641        if (sIsBoosted.get() == 0) {
642            // boost to prio 118 while holding a global lock
643            Process.setThreadPriority(Process.myTid(), -2);
644            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
645        }
646        int cur = sIsBoosted.get();
647        sIsBoosted.set(cur + 1);
648    }
649
650    static void resetPriorityAfterLockedSection() {
651        sIsBoosted.set(sIsBoosted.get() - 1);
652        if (sIsBoosted.get() == 0) {
653            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
654            Process.setThreadPriority(Process.myTid(), 0);
655        }
656    }
657    public class PendingAssistExtras extends Binder implements Runnable {
658        public final ActivityRecord activity;
659        public final Bundle extras;
660        public final Intent intent;
661        public final String hint;
662        public final IResultReceiver receiver;
663        public final int userHandle;
664        public boolean haveResult = false;
665        public Bundle result = null;
666        public AssistStructure structure = null;
667        public AssistContent content = null;
668        public Bundle receiverExtras;
669
670        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
671                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
672            activity = _activity;
673            extras = _extras;
674            intent = _intent;
675            hint = _hint;
676            receiver = _receiver;
677            receiverExtras = _receiverExtras;
678            userHandle = _userHandle;
679        }
680        @Override
681        public void run() {
682            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
683            synchronized (this) {
684                haveResult = true;
685                notifyAll();
686            }
687            pendingAssistExtrasTimedOut(this);
688        }
689    }
690
691    final ArrayList<PendingAssistExtras> mPendingAssistExtras
692            = new ArrayList<PendingAssistExtras>();
693
694    /**
695     * Process management.
696     */
697    final ProcessList mProcessList = new ProcessList();
698
699    /**
700     * All of the applications we currently have running organized by name.
701     * The keys are strings of the application package name (as
702     * returned by the package manager), and the keys are ApplicationRecord
703     * objects.
704     */
705    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
706
707    /**
708     * Tracking long-term execution of processes to look for abuse and other
709     * bad app behavior.
710     */
711    final ProcessStatsService mProcessStats;
712
713    /**
714     * The currently running isolated processes.
715     */
716    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
717
718    /**
719     * Counter for assigning isolated process uids, to avoid frequently reusing the
720     * same ones.
721     */
722    int mNextIsolatedProcessUid = 0;
723
724    /**
725     * The currently running heavy-weight process, if any.
726     */
727    ProcessRecord mHeavyWeightProcess = null;
728
729    /**
730     * All of the processes we currently have running organized by pid.
731     * The keys are the pid running the application.
732     *
733     * <p>NOTE: This object is protected by its own lock, NOT the global
734     * activity manager lock!
735     */
736    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
737
738    /**
739     * All of the processes that have been forced to be foreground.  The key
740     * is the pid of the caller who requested it (we hold a death
741     * link on it).
742     */
743    abstract class ForegroundToken implements IBinder.DeathRecipient {
744        int pid;
745        IBinder token;
746    }
747    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
748
749    /**
750     * List of records for processes that someone had tried to start before the
751     * system was ready.  We don't start them at that point, but ensure they
752     * are started by the time booting is complete.
753     */
754    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
755
756    /**
757     * List of persistent applications that are in the process
758     * of being started.
759     */
760    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
761
762    /**
763     * Processes that are being forcibly torn down.
764     */
765    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
766
767    /**
768     * List of running applications, sorted by recent usage.
769     * The first entry in the list is the least recently used.
770     */
771    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
772
773    /**
774     * Where in mLruProcesses that the processes hosting activities start.
775     */
776    int mLruProcessActivityStart = 0;
777
778    /**
779     * Where in mLruProcesses that the processes hosting services start.
780     * This is after (lower index) than mLruProcessesActivityStart.
781     */
782    int mLruProcessServiceStart = 0;
783
784    /**
785     * List of processes that should gc as soon as things are idle.
786     */
787    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
788
789    /**
790     * Processes we want to collect PSS data from.
791     */
792    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
793
794    private boolean mBinderTransactionTrackingEnabled = false;
795
796    /**
797     * Last time we requested PSS data of all processes.
798     */
799    long mLastFullPssTime = SystemClock.uptimeMillis();
800
801    /**
802     * If set, the next time we collect PSS data we should do a full collection
803     * with data from native processes and the kernel.
804     */
805    boolean mFullPssPending = false;
806
807    /**
808     * This is the process holding what we currently consider to be
809     * the "home" activity.
810     */
811    ProcessRecord mHomeProcess;
812
813    /**
814     * This is the process holding the activity the user last visited that
815     * is in a different process from the one they are currently in.
816     */
817    ProcessRecord mPreviousProcess;
818
819    /**
820     * The time at which the previous process was last visible.
821     */
822    long mPreviousProcessVisibleTime;
823
824    /**
825     * Track all uids that have actively running processes.
826     */
827    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
828
829    /**
830     * This is for verifying the UID report flow.
831     */
832    static final boolean VALIDATE_UID_STATES = true;
833    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
834
835    /**
836     * Packages that the user has asked to have run in screen size
837     * compatibility mode instead of filling the screen.
838     */
839    final CompatModePackages mCompatModePackages;
840
841    /**
842     * Set of IntentSenderRecord objects that are currently active.
843     */
844    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
845            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
846
847    /**
848     * Fingerprints (hashCode()) of stack traces that we've
849     * already logged DropBox entries for.  Guarded by itself.  If
850     * something (rogue user app) forces this over
851     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
852     */
853    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
854    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
855
856    /**
857     * Strict Mode background batched logging state.
858     *
859     * The string buffer is guarded by itself, and its lock is also
860     * used to determine if another batched write is already
861     * in-flight.
862     */
863    private final StringBuilder mStrictModeBuffer = new StringBuilder();
864
865    /**
866     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
867     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
868     */
869    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
870
871    /**
872     * Resolver for broadcast intents to registered receivers.
873     * Holds BroadcastFilter (subclass of IntentFilter).
874     */
875    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
876            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
877        @Override
878        protected boolean allowFilterResult(
879                BroadcastFilter filter, List<BroadcastFilter> dest) {
880            IBinder target = filter.receiverList.receiver.asBinder();
881            for (int i = dest.size() - 1; i >= 0; i--) {
882                if (dest.get(i).receiverList.receiver.asBinder() == target) {
883                    return false;
884                }
885            }
886            return true;
887        }
888
889        @Override
890        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
891            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
892                    || userId == filter.owningUserId) {
893                return super.newResult(filter, match, userId);
894            }
895            return null;
896        }
897
898        @Override
899        protected BroadcastFilter[] newArray(int size) {
900            return new BroadcastFilter[size];
901        }
902
903        @Override
904        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
905            return packageName.equals(filter.packageName);
906        }
907    };
908
909    /**
910     * State of all active sticky broadcasts per user.  Keys are the action of the
911     * sticky Intent, values are an ArrayList of all broadcasted intents with
912     * that action (which should usually be one).  The SparseArray is keyed
913     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
914     * for stickies that are sent to all users.
915     */
916    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
917            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
918
919    final ActiveServices mServices;
920
921    final static class Association {
922        final int mSourceUid;
923        final String mSourceProcess;
924        final int mTargetUid;
925        final ComponentName mTargetComponent;
926        final String mTargetProcess;
927
928        int mCount;
929        long mTime;
930
931        int mNesting;
932        long mStartTime;
933
934        // states of the source process when the bind occurred.
935        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
936        long mLastStateUptime;
937        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
938                - ActivityManager.MIN_PROCESS_STATE+1];
939
940        Association(int sourceUid, String sourceProcess, int targetUid,
941                ComponentName targetComponent, String targetProcess) {
942            mSourceUid = sourceUid;
943            mSourceProcess = sourceProcess;
944            mTargetUid = targetUid;
945            mTargetComponent = targetComponent;
946            mTargetProcess = targetProcess;
947        }
948    }
949
950    /**
951     * When service association tracking is enabled, this is all of the associations we
952     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
953     * -> association data.
954     */
955    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
956            mAssociations = new SparseArray<>();
957    boolean mTrackingAssociations;
958
959    /**
960     * Backup/restore process management
961     */
962    String mBackupAppName = null;
963    BackupRecord mBackupTarget = null;
964
965    final ProviderMap mProviderMap;
966
967    /**
968     * List of content providers who have clients waiting for them.  The
969     * application is currently being launched and the provider will be
970     * removed from this list once it is published.
971     */
972    final ArrayList<ContentProviderRecord> mLaunchingProviders
973            = new ArrayList<ContentProviderRecord>();
974
975    /**
976     * File storing persisted {@link #mGrantedUriPermissions}.
977     */
978    private final AtomicFile mGrantFile;
979
980    /** XML constants used in {@link #mGrantFile} */
981    private static final String TAG_URI_GRANTS = "uri-grants";
982    private static final String TAG_URI_GRANT = "uri-grant";
983    private static final String ATTR_USER_HANDLE = "userHandle";
984    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
985    private static final String ATTR_TARGET_USER_ID = "targetUserId";
986    private static final String ATTR_SOURCE_PKG = "sourcePkg";
987    private static final String ATTR_TARGET_PKG = "targetPkg";
988    private static final String ATTR_URI = "uri";
989    private static final String ATTR_MODE_FLAGS = "modeFlags";
990    private static final String ATTR_CREATED_TIME = "createdTime";
991    private static final String ATTR_PREFIX = "prefix";
992
993    /**
994     * Global set of specific {@link Uri} permissions that have been granted.
995     * This optimized lookup structure maps from {@link UriPermission#targetUid}
996     * to {@link UriPermission#uri} to {@link UriPermission}.
997     */
998    @GuardedBy("this")
999    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1000            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1001
1002    public static class GrantUri {
1003        public final int sourceUserId;
1004        public final Uri uri;
1005        public boolean prefix;
1006
1007        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1008            this.sourceUserId = sourceUserId;
1009            this.uri = uri;
1010            this.prefix = prefix;
1011        }
1012
1013        @Override
1014        public int hashCode() {
1015            int hashCode = 1;
1016            hashCode = 31 * hashCode + sourceUserId;
1017            hashCode = 31 * hashCode + uri.hashCode();
1018            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1019            return hashCode;
1020        }
1021
1022        @Override
1023        public boolean equals(Object o) {
1024            if (o instanceof GrantUri) {
1025                GrantUri other = (GrantUri) o;
1026                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1027                        && prefix == other.prefix;
1028            }
1029            return false;
1030        }
1031
1032        @Override
1033        public String toString() {
1034            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1035            if (prefix) result += " [prefix]";
1036            return result;
1037        }
1038
1039        public String toSafeString() {
1040            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1041            if (prefix) result += " [prefix]";
1042            return result;
1043        }
1044
1045        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1046            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1047                    ContentProvider.getUriWithoutUserId(uri), false);
1048        }
1049    }
1050
1051    CoreSettingsObserver mCoreSettingsObserver;
1052
1053    FontScaleSettingObserver mFontScaleSettingObserver;
1054
1055    private final class FontScaleSettingObserver extends ContentObserver {
1056        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1057
1058        public FontScaleSettingObserver() {
1059            super(mHandler);
1060            ContentResolver resolver = mContext.getContentResolver();
1061            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1062        }
1063
1064        @Override
1065        public void onChange(boolean selfChange, Uri uri) {
1066            if (mFontScaleUri.equals(uri)) {
1067                updateFontScaleIfNeeded();
1068            }
1069        }
1070    }
1071
1072    /**
1073     * Thread-local storage used to carry caller permissions over through
1074     * indirect content-provider access.
1075     */
1076    private class Identity {
1077        public final IBinder token;
1078        public final int pid;
1079        public final int uid;
1080
1081        Identity(IBinder _token, int _pid, int _uid) {
1082            token = _token;
1083            pid = _pid;
1084            uid = _uid;
1085        }
1086    }
1087
1088    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1089
1090    /**
1091     * All information we have collected about the runtime performance of
1092     * any user id that can impact battery performance.
1093     */
1094    final BatteryStatsService mBatteryStatsService;
1095
1096    /**
1097     * Information about component usage
1098     */
1099    UsageStatsManagerInternal mUsageStatsService;
1100
1101    /**
1102     * Access to DeviceIdleController service.
1103     */
1104    DeviceIdleController.LocalService mLocalDeviceIdleController;
1105
1106    /**
1107     * Information about and control over application operations
1108     */
1109    final AppOpsService mAppOpsService;
1110
1111    /**
1112     * Current configuration information.  HistoryRecord objects are given
1113     * a reference to this object to indicate which configuration they are
1114     * currently running in, so this object must be kept immutable.
1115     */
1116    Configuration mConfiguration = new Configuration();
1117
1118    /**
1119     * Current sequencing integer of the configuration, for skipping old
1120     * configurations.
1121     */
1122    int mConfigurationSeq = 0;
1123
1124    boolean mSuppressResizeConfigChanges = false;
1125
1126    /**
1127     * Hardware-reported OpenGLES version.
1128     */
1129    final int GL_ES_VERSION;
1130
1131    /**
1132     * List of initialization arguments to pass to all processes when binding applications to them.
1133     * For example, references to the commonly used services.
1134     */
1135    HashMap<String, IBinder> mAppBindArgs;
1136
1137    /**
1138     * Temporary to avoid allocations.  Protected by main lock.
1139     */
1140    final StringBuilder mStringBuilder = new StringBuilder(256);
1141
1142    /**
1143     * Used to control how we initialize the service.
1144     */
1145    ComponentName mTopComponent;
1146    String mTopAction = Intent.ACTION_MAIN;
1147    String mTopData;
1148
1149    volatile boolean mProcessesReady = false;
1150    volatile boolean mSystemReady = false;
1151    volatile boolean mOnBattery = false;
1152    volatile int mFactoryTest;
1153
1154    @GuardedBy("this") boolean mBooting = false;
1155    @GuardedBy("this") boolean mCallFinishBooting = false;
1156    @GuardedBy("this") boolean mBootAnimationComplete = false;
1157    @GuardedBy("this") boolean mLaunchWarningShown = false;
1158    @GuardedBy("this") boolean mCheckedForSetup = false;
1159
1160    Context mContext;
1161
1162    /**
1163     * The time at which we will allow normal application switches again,
1164     * after a call to {@link #stopAppSwitches()}.
1165     */
1166    long mAppSwitchesAllowedTime;
1167
1168    /**
1169     * This is set to true after the first switch after mAppSwitchesAllowedTime
1170     * is set; any switches after that will clear the time.
1171     */
1172    boolean mDidAppSwitch;
1173
1174    /**
1175     * Last time (in realtime) at which we checked for power usage.
1176     */
1177    long mLastPowerCheckRealtime;
1178
1179    /**
1180     * Last time (in uptime) at which we checked for power usage.
1181     */
1182    long mLastPowerCheckUptime;
1183
1184    /**
1185     * Set while we are wanting to sleep, to prevent any
1186     * activities from being started/resumed.
1187     */
1188    private boolean mSleeping = false;
1189
1190    /**
1191     * The process state used for processes that are running the top activities.
1192     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1193     */
1194    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1195
1196    /**
1197     * Set while we are running a voice interaction.  This overrides
1198     * sleeping while it is active.
1199     */
1200    private IVoiceInteractionSession mRunningVoice;
1201
1202    /**
1203     * For some direct access we need to power manager.
1204     */
1205    PowerManagerInternal mLocalPowerManager;
1206
1207    /**
1208     * We want to hold a wake lock while running a voice interaction session, since
1209     * this may happen with the screen off and we need to keep the CPU running to
1210     * be able to continue to interact with the user.
1211     */
1212    PowerManager.WakeLock mVoiceWakeLock;
1213
1214    /**
1215     * State of external calls telling us if the device is awake or asleep.
1216     */
1217    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1218
1219    /**
1220     * A list of tokens that cause the top activity to be put to sleep.
1221     * They are used by components that may hide and block interaction with underlying
1222     * activities.
1223     */
1224    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1225
1226    static final int LOCK_SCREEN_HIDDEN = 0;
1227    static final int LOCK_SCREEN_LEAVING = 1;
1228    static final int LOCK_SCREEN_SHOWN = 2;
1229    /**
1230     * State of external call telling us if the lock screen is shown.
1231     */
1232    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1233
1234    /**
1235     * Set if we are shutting down the system, similar to sleeping.
1236     */
1237    boolean mShuttingDown = false;
1238
1239    /**
1240     * Current sequence id for oom_adj computation traversal.
1241     */
1242    int mAdjSeq = 0;
1243
1244    /**
1245     * Current sequence id for process LRU updating.
1246     */
1247    int mLruSeq = 0;
1248
1249    /**
1250     * Keep track of the non-cached/empty process we last found, to help
1251     * determine how to distribute cached/empty processes next time.
1252     */
1253    int mNumNonCachedProcs = 0;
1254
1255    /**
1256     * Keep track of the number of cached hidden procs, to balance oom adj
1257     * distribution between those and empty procs.
1258     */
1259    int mNumCachedHiddenProcs = 0;
1260
1261    /**
1262     * Keep track of the number of service processes we last found, to
1263     * determine on the next iteration which should be B services.
1264     */
1265    int mNumServiceProcs = 0;
1266    int mNewNumAServiceProcs = 0;
1267    int mNewNumServiceProcs = 0;
1268
1269    /**
1270     * Allow the current computed overall memory level of the system to go down?
1271     * This is set to false when we are killing processes for reasons other than
1272     * memory management, so that the now smaller process list will not be taken as
1273     * an indication that memory is tighter.
1274     */
1275    boolean mAllowLowerMemLevel = false;
1276
1277    /**
1278     * The last computed memory level, for holding when we are in a state that
1279     * processes are going away for other reasons.
1280     */
1281    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1282
1283    /**
1284     * The last total number of process we have, to determine if changes actually look
1285     * like a shrinking number of process due to lower RAM.
1286     */
1287    int mLastNumProcesses;
1288
1289    /**
1290     * The uptime of the last time we performed idle maintenance.
1291     */
1292    long mLastIdleTime = SystemClock.uptimeMillis();
1293
1294    /**
1295     * Total time spent with RAM that has been added in the past since the last idle time.
1296     */
1297    long mLowRamTimeSinceLastIdle = 0;
1298
1299    /**
1300     * If RAM is currently low, when that horrible situation started.
1301     */
1302    long mLowRamStartTime = 0;
1303
1304    /**
1305     * For reporting to battery stats the current top application.
1306     */
1307    private String mCurResumedPackage = null;
1308    private int mCurResumedUid = -1;
1309
1310    /**
1311     * For reporting to battery stats the apps currently running foreground
1312     * service.  The ProcessMap is package/uid tuples; each of these contain
1313     * an array of the currently foreground processes.
1314     */
1315    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1316            = new ProcessMap<ArrayList<ProcessRecord>>();
1317
1318    /**
1319     * This is set if we had to do a delayed dexopt of an app before launching
1320     * it, to increase the ANR timeouts in that case.
1321     */
1322    boolean mDidDexOpt;
1323
1324    /**
1325     * Set if the systemServer made a call to enterSafeMode.
1326     */
1327    boolean mSafeMode;
1328
1329    /**
1330     * If true, we are running under a test environment so will sample PSS from processes
1331     * much more rapidly to try to collect better data when the tests are rapidly
1332     * running through apps.
1333     */
1334    boolean mTestPssMode = false;
1335
1336    String mDebugApp = null;
1337    boolean mWaitForDebugger = false;
1338    boolean mDebugTransient = false;
1339    String mOrigDebugApp = null;
1340    boolean mOrigWaitForDebugger = false;
1341    boolean mAlwaysFinishActivities = false;
1342    boolean mLenientBackgroundCheck = false;
1343    boolean mForceResizableActivities;
1344    boolean mSupportsMultiWindow;
1345    boolean mSupportsFreeformWindowManagement;
1346    boolean mSupportsPictureInPicture;
1347    Rect mDefaultPinnedStackBounds;
1348    IActivityController mController = null;
1349    boolean mControllerIsAMonkey = false;
1350    String mProfileApp = null;
1351    ProcessRecord mProfileProc = null;
1352    String mProfileFile;
1353    ParcelFileDescriptor mProfileFd;
1354    int mSamplingInterval = 0;
1355    boolean mAutoStopProfiler = false;
1356    int mProfileType = 0;
1357    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1358    String mMemWatchDumpProcName;
1359    String mMemWatchDumpFile;
1360    int mMemWatchDumpPid;
1361    int mMemWatchDumpUid;
1362    String mTrackAllocationApp = null;
1363    String mNativeDebuggingApp = null;
1364
1365    final long[] mTmpLong = new long[2];
1366
1367    static final class ProcessChangeItem {
1368        static final int CHANGE_ACTIVITIES = 1<<0;
1369        static final int CHANGE_PROCESS_STATE = 1<<1;
1370        int changes;
1371        int uid;
1372        int pid;
1373        int processState;
1374        boolean foregroundActivities;
1375    }
1376
1377    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1378    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1379
1380    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1381    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1382
1383    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1384    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1385
1386    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1387    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1388
1389    /**
1390     * Runtime CPU use collection thread.  This object's lock is used to
1391     * perform synchronization with the thread (notifying it to run).
1392     */
1393    final Thread mProcessCpuThread;
1394
1395    /**
1396     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1397     * Must acquire this object's lock when accessing it.
1398     * NOTE: this lock will be held while doing long operations (trawling
1399     * through all processes in /proc), so it should never be acquired by
1400     * any critical paths such as when holding the main activity manager lock.
1401     */
1402    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1403            MONITOR_THREAD_CPU_USAGE);
1404    final AtomicLong mLastCpuTime = new AtomicLong(0);
1405    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1406
1407    long mLastWriteTime = 0;
1408
1409    /**
1410     * Used to retain an update lock when the foreground activity is in
1411     * immersive mode.
1412     */
1413    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1414
1415    /**
1416     * Set to true after the system has finished booting.
1417     */
1418    boolean mBooted = false;
1419
1420    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1421    int mProcessLimitOverride = -1;
1422
1423    WindowManagerService mWindowManager;
1424    final ActivityThread mSystemThread;
1425
1426    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1427        final ProcessRecord mApp;
1428        final int mPid;
1429        final IApplicationThread mAppThread;
1430
1431        AppDeathRecipient(ProcessRecord app, int pid,
1432                IApplicationThread thread) {
1433            if (DEBUG_ALL) Slog.v(
1434                TAG, "New death recipient " + this
1435                + " for thread " + thread.asBinder());
1436            mApp = app;
1437            mPid = pid;
1438            mAppThread = thread;
1439        }
1440
1441        @Override
1442        public void binderDied() {
1443            if (DEBUG_ALL) Slog.v(
1444                TAG, "Death received in " + this
1445                + " for thread " + mAppThread.asBinder());
1446            synchronized(ActivityManagerService.this) {
1447                appDiedLocked(mApp, mPid, mAppThread, true);
1448            }
1449        }
1450    }
1451
1452    static final int SHOW_ERROR_UI_MSG = 1;
1453    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1454    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1455    static final int UPDATE_CONFIGURATION_MSG = 4;
1456    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1457    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1458    static final int SERVICE_TIMEOUT_MSG = 12;
1459    static final int UPDATE_TIME_ZONE = 13;
1460    static final int SHOW_UID_ERROR_UI_MSG = 14;
1461    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1462    static final int PROC_START_TIMEOUT_MSG = 20;
1463    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1464    static final int KILL_APPLICATION_MSG = 22;
1465    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1466    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1467    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1468    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1469    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1470    static final int CLEAR_DNS_CACHE_MSG = 28;
1471    static final int UPDATE_HTTP_PROXY_MSG = 29;
1472    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1473    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1474    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1475    static final int REPORT_MEM_USAGE_MSG = 33;
1476    static final int REPORT_USER_SWITCH_MSG = 34;
1477    static final int CONTINUE_USER_SWITCH_MSG = 35;
1478    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1479    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1480    static final int PERSIST_URI_GRANTS_MSG = 38;
1481    static final int REQUEST_ALL_PSS_MSG = 39;
1482    static final int START_PROFILES_MSG = 40;
1483    static final int UPDATE_TIME = 41;
1484    static final int SYSTEM_USER_START_MSG = 42;
1485    static final int SYSTEM_USER_CURRENT_MSG = 43;
1486    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1487    static final int FINISH_BOOTING_MSG = 45;
1488    static final int START_USER_SWITCH_UI_MSG = 46;
1489    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1490    static final int DISMISS_DIALOG_UI_MSG = 48;
1491    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1492    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1493    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1494    static final int DELETE_DUMPHEAP_MSG = 52;
1495    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1496    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1497    static final int REPORT_TIME_TRACKER_MSG = 55;
1498    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1499    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1500    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1501    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1502    static final int IDLE_UIDS_MSG = 60;
1503    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1504    static final int LOG_STACK_STATE = 62;
1505    static final int VR_MODE_CHANGE_MSG = 63;
1506    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1507    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1508    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1509    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1510    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1511    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1512
1513    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1514    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1515    static final int FIRST_COMPAT_MODE_MSG = 300;
1516    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1517
1518    static ServiceThread sKillThread = null;
1519    static KillHandler sKillHandler = null;
1520
1521    CompatModeDialog mCompatModeDialog;
1522    long mLastMemUsageReportTime = 0;
1523
1524    /**
1525     * Flag whether the current user is a "monkey", i.e. whether
1526     * the UI is driven by a UI automation tool.
1527     */
1528    private boolean mUserIsMonkey;
1529
1530    /** Flag whether the device has a Recents UI */
1531    boolean mHasRecents;
1532
1533    /** The dimensions of the thumbnails in the Recents UI. */
1534    int mThumbnailWidth;
1535    int mThumbnailHeight;
1536    float mFullscreenThumbnailScale;
1537
1538    final ServiceThread mHandlerThread;
1539    final MainHandler mHandler;
1540    final UiHandler mUiHandler;
1541
1542    PackageManagerInternal mPackageManagerInt;
1543
1544    // VoiceInteraction session ID that changes for each new request except when
1545    // being called for multiwindow assist in a single session.
1546    private int mViSessionId = 1000;
1547
1548    final class KillHandler extends Handler {
1549        static final int KILL_PROCESS_GROUP_MSG = 4000;
1550
1551        public KillHandler(Looper looper) {
1552            super(looper, null, true);
1553        }
1554
1555        @Override
1556        public void handleMessage(Message msg) {
1557            switch (msg.what) {
1558                case KILL_PROCESS_GROUP_MSG:
1559                {
1560                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1561                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1562                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1563                }
1564                break;
1565
1566                default:
1567                    super.handleMessage(msg);
1568            }
1569        }
1570    }
1571
1572    final class UiHandler extends Handler {
1573        public UiHandler() {
1574            super(com.android.server.UiThread.get().getLooper(), null, true);
1575        }
1576
1577        @Override
1578        public void handleMessage(Message msg) {
1579            switch (msg.what) {
1580            case SHOW_ERROR_UI_MSG: {
1581                mAppErrors.handleShowAppErrorUi(msg);
1582                ensureBootCompleted();
1583            } break;
1584            case SHOW_NOT_RESPONDING_UI_MSG: {
1585                mAppErrors.handleShowAnrUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1589                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1590                synchronized (ActivityManagerService.this) {
1591                    ProcessRecord proc = (ProcessRecord) data.get("app");
1592                    if (proc == null) {
1593                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1594                        break;
1595                    }
1596                    if (proc.crashDialog != null) {
1597                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1598                        return;
1599                    }
1600                    AppErrorResult res = (AppErrorResult) data.get("result");
1601                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1602                        Dialog d = new StrictModeViolationDialog(mContext,
1603                                ActivityManagerService.this, res, proc);
1604                        d.show();
1605                        proc.crashDialog = d;
1606                    } else {
1607                        // The device is asleep, so just pretend that the user
1608                        // saw a crash dialog and hit "force quit".
1609                        res.set(0);
1610                    }
1611                }
1612                ensureBootCompleted();
1613            } break;
1614            case SHOW_FACTORY_ERROR_UI_MSG: {
1615                Dialog d = new FactoryErrorDialog(
1616                    mContext, msg.getData().getCharSequence("msg"));
1617                d.show();
1618                ensureBootCompleted();
1619            } break;
1620            case WAIT_FOR_DEBUGGER_UI_MSG: {
1621                synchronized (ActivityManagerService.this) {
1622                    ProcessRecord app = (ProcessRecord)msg.obj;
1623                    if (msg.arg1 != 0) {
1624                        if (!app.waitedForDebugger) {
1625                            Dialog d = new AppWaitingForDebuggerDialog(
1626                                    ActivityManagerService.this,
1627                                    mContext, app);
1628                            app.waitDialog = d;
1629                            app.waitedForDebugger = true;
1630                            d.show();
1631                        }
1632                    } else {
1633                        if (app.waitDialog != null) {
1634                            app.waitDialog.dismiss();
1635                            app.waitDialog = null;
1636                        }
1637                    }
1638                }
1639            } break;
1640            case SHOW_UID_ERROR_UI_MSG: {
1641                if (mShowDialogs) {
1642                    AlertDialog d = new BaseErrorDialog(mContext);
1643                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1644                    d.setCancelable(false);
1645                    d.setTitle(mContext.getText(R.string.android_system_label));
1646                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1647                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1648                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1649                    d.show();
1650                }
1651            } break;
1652            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1653                if (mShowDialogs) {
1654                    AlertDialog d = new BaseErrorDialog(mContext);
1655                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1656                    d.setCancelable(false);
1657                    d.setTitle(mContext.getText(R.string.android_system_label));
1658                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1659                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1660                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1661                    d.show();
1662                }
1663            } break;
1664            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1665                synchronized (ActivityManagerService.this) {
1666                    ActivityRecord ar = (ActivityRecord) msg.obj;
1667                    if (mCompatModeDialog != null) {
1668                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1669                                ar.info.applicationInfo.packageName)) {
1670                            return;
1671                        }
1672                        mCompatModeDialog.dismiss();
1673                        mCompatModeDialog = null;
1674                    }
1675                    if (ar != null && false) {
1676                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1677                                ar.packageName)) {
1678                            int mode = mCompatModePackages.computeCompatModeLocked(
1679                                    ar.info.applicationInfo);
1680                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1681                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1682                                mCompatModeDialog = new CompatModeDialog(
1683                                        ActivityManagerService.this, mContext,
1684                                        ar.info.applicationInfo);
1685                                mCompatModeDialog.show();
1686                            }
1687                        }
1688                    }
1689                }
1690                break;
1691            }
1692            case START_USER_SWITCH_UI_MSG: {
1693                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1694                break;
1695            }
1696            case DISMISS_DIALOG_UI_MSG: {
1697                final Dialog d = (Dialog) msg.obj;
1698                d.dismiss();
1699                break;
1700            }
1701            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1702                dispatchProcessesChanged();
1703                break;
1704            }
1705            case DISPATCH_PROCESS_DIED_UI_MSG: {
1706                final int pid = msg.arg1;
1707                final int uid = msg.arg2;
1708                dispatchProcessDied(pid, uid);
1709                break;
1710            }
1711            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1712                dispatchUidsChanged();
1713            } break;
1714            }
1715        }
1716    }
1717
1718    final class MainHandler extends Handler {
1719        public MainHandler(Looper looper) {
1720            super(looper, null, true);
1721        }
1722
1723        @Override
1724        public void handleMessage(Message msg) {
1725            switch (msg.what) {
1726            case UPDATE_CONFIGURATION_MSG: {
1727                final ContentResolver resolver = mContext.getContentResolver();
1728                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1729                        msg.arg1);
1730            } break;
1731            case GC_BACKGROUND_PROCESSES_MSG: {
1732                synchronized (ActivityManagerService.this) {
1733                    performAppGcsIfAppropriateLocked();
1734                }
1735            } break;
1736            case SERVICE_TIMEOUT_MSG: {
1737                if (mDidDexOpt) {
1738                    mDidDexOpt = false;
1739                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1740                    nmsg.obj = msg.obj;
1741                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1742                    return;
1743                }
1744                mServices.serviceTimeout((ProcessRecord)msg.obj);
1745            } break;
1746            case UPDATE_TIME_ZONE: {
1747                synchronized (ActivityManagerService.this) {
1748                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1749                        ProcessRecord r = mLruProcesses.get(i);
1750                        if (r.thread != null) {
1751                            try {
1752                                r.thread.updateTimeZone();
1753                            } catch (RemoteException ex) {
1754                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1755                            }
1756                        }
1757                    }
1758                }
1759            } break;
1760            case CLEAR_DNS_CACHE_MSG: {
1761                synchronized (ActivityManagerService.this) {
1762                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1763                        ProcessRecord r = mLruProcesses.get(i);
1764                        if (r.thread != null) {
1765                            try {
1766                                r.thread.clearDnsCache();
1767                            } catch (RemoteException ex) {
1768                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1769                            }
1770                        }
1771                    }
1772                }
1773            } break;
1774            case UPDATE_HTTP_PROXY_MSG: {
1775                ProxyInfo proxy = (ProxyInfo)msg.obj;
1776                String host = "";
1777                String port = "";
1778                String exclList = "";
1779                Uri pacFileUrl = Uri.EMPTY;
1780                if (proxy != null) {
1781                    host = proxy.getHost();
1782                    port = Integer.toString(proxy.getPort());
1783                    exclList = proxy.getExclusionListAsString();
1784                    pacFileUrl = proxy.getPacFileUrl();
1785                }
1786                synchronized (ActivityManagerService.this) {
1787                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1788                        ProcessRecord r = mLruProcesses.get(i);
1789                        if (r.thread != null) {
1790                            try {
1791                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1792                            } catch (RemoteException ex) {
1793                                Slog.w(TAG, "Failed to update http proxy for: " +
1794                                        r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799            } break;
1800            case PROC_START_TIMEOUT_MSG: {
1801                if (mDidDexOpt) {
1802                    mDidDexOpt = false;
1803                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1804                    nmsg.obj = msg.obj;
1805                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1806                    return;
1807                }
1808                ProcessRecord app = (ProcessRecord)msg.obj;
1809                synchronized (ActivityManagerService.this) {
1810                    processStartTimedOutLocked(app);
1811                }
1812            } break;
1813            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1814                ProcessRecord app = (ProcessRecord)msg.obj;
1815                synchronized (ActivityManagerService.this) {
1816                    processContentProviderPublishTimedOutLocked(app);
1817                }
1818            } break;
1819            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1820                synchronized (ActivityManagerService.this) {
1821                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1822                }
1823            } break;
1824            case KILL_APPLICATION_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    int appid = msg.arg1;
1827                    boolean restart = (msg.arg2 == 1);
1828                    Bundle bundle = (Bundle)msg.obj;
1829                    String pkg = bundle.getString("pkg");
1830                    String reason = bundle.getString("reason");
1831                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1832                            false, UserHandle.USER_ALL, reason);
1833                }
1834            } break;
1835            case FINALIZE_PENDING_INTENT_MSG: {
1836                ((PendingIntentRecord)msg.obj).completeFinalize();
1837            } break;
1838            case POST_HEAVY_NOTIFICATION_MSG: {
1839                INotificationManager inm = NotificationManager.getService();
1840                if (inm == null) {
1841                    return;
1842                }
1843
1844                ActivityRecord root = (ActivityRecord)msg.obj;
1845                ProcessRecord process = root.app;
1846                if (process == null) {
1847                    return;
1848                }
1849
1850                try {
1851                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1852                    String text = mContext.getString(R.string.heavy_weight_notification,
1853                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1854                    Notification notification = new Notification.Builder(context)
1855                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1856                            .setWhen(0)
1857                            .setOngoing(true)
1858                            .setTicker(text)
1859                            .setColor(mContext.getColor(
1860                                    com.android.internal.R.color.system_notification_accent_color))
1861                            .setContentTitle(text)
1862                            .setContentText(
1863                                    mContext.getText(R.string.heavy_weight_notification_detail))
1864                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1865                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1866                                    new UserHandle(root.userId)))
1867                            .build();
1868                    try {
1869                        int[] outId = new int[1];
1870                        inm.enqueueNotificationWithTag("android", "android", null,
1871                                R.string.heavy_weight_notification,
1872                                notification, outId, root.userId);
1873                    } catch (RuntimeException e) {
1874                        Slog.w(ActivityManagerService.TAG,
1875                                "Error showing notification for heavy-weight app", e);
1876                    } catch (RemoteException e) {
1877                    }
1878                } catch (NameNotFoundException e) {
1879                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1880                }
1881            } break;
1882            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1883                INotificationManager inm = NotificationManager.getService();
1884                if (inm == null) {
1885                    return;
1886                }
1887                try {
1888                    inm.cancelNotificationWithTag("android", null,
1889                            R.string.heavy_weight_notification,  msg.arg1);
1890                } catch (RuntimeException e) {
1891                    Slog.w(ActivityManagerService.TAG,
1892                            "Error canceling notification for service", e);
1893                } catch (RemoteException e) {
1894                }
1895            } break;
1896            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1897                synchronized (ActivityManagerService.this) {
1898                    checkExcessivePowerUsageLocked(true);
1899                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1900                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1901                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1902                }
1903            } break;
1904            case REPORT_MEM_USAGE_MSG: {
1905                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1906                Thread thread = new Thread() {
1907                    @Override public void run() {
1908                        reportMemUsage(memInfos);
1909                    }
1910                };
1911                thread.start();
1912                break;
1913            }
1914            case REPORT_USER_SWITCH_MSG: {
1915                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1916                break;
1917            }
1918            case CONTINUE_USER_SWITCH_MSG: {
1919                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case USER_SWITCH_TIMEOUT_MSG: {
1923                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case IMMERSIVE_MODE_LOCK_MSG: {
1927                final boolean nextState = (msg.arg1 != 0);
1928                if (mUpdateLock.isHeld() != nextState) {
1929                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1930                            "Applying new update lock state '" + nextState
1931                            + "' for " + (ActivityRecord)msg.obj);
1932                    if (nextState) {
1933                        mUpdateLock.acquire();
1934                    } else {
1935                        mUpdateLock.release();
1936                    }
1937                }
1938                break;
1939            }
1940            case PERSIST_URI_GRANTS_MSG: {
1941                writeGrantedUriPermissions();
1942                break;
1943            }
1944            case REQUEST_ALL_PSS_MSG: {
1945                synchronized (ActivityManagerService.this) {
1946                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1947                }
1948                break;
1949            }
1950            case START_PROFILES_MSG: {
1951                synchronized (ActivityManagerService.this) {
1952                    mUserController.startProfilesLocked();
1953                }
1954                break;
1955            }
1956            case UPDATE_TIME: {
1957                synchronized (ActivityManagerService.this) {
1958                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1959                        ProcessRecord r = mLruProcesses.get(i);
1960                        if (r.thread != null) {
1961                            try {
1962                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1963                            } catch (RemoteException ex) {
1964                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1965                            }
1966                        }
1967                    }
1968                }
1969                break;
1970            }
1971            case SYSTEM_USER_START_MSG: {
1972                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1973                        Integer.toString(msg.arg1), msg.arg1);
1974                mSystemServiceManager.startUser(msg.arg1);
1975                break;
1976            }
1977            case SYSTEM_USER_UNLOCK_MSG: {
1978                final int userId = msg.arg1;
1979                mSystemServiceManager.unlockUser(userId);
1980                synchronized (ActivityManagerService.this) {
1981                    mRecentTasks.loadUserRecentsLocked(userId);
1982                }
1983                if (userId == UserHandle.USER_SYSTEM) {
1984                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1985                }
1986                installEncryptionUnawareProviders(userId);
1987                mUserController.finishUserUnlocked((UserState) msg.obj);
1988                break;
1989            }
1990            case SYSTEM_USER_CURRENT_MSG: {
1991                mBatteryStatsService.noteEvent(
1992                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1993                        Integer.toString(msg.arg2), msg.arg2);
1994                mBatteryStatsService.noteEvent(
1995                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1996                        Integer.toString(msg.arg1), msg.arg1);
1997                mSystemServiceManager.switchUser(msg.arg1);
1998                break;
1999            }
2000            case ENTER_ANIMATION_COMPLETE_MSG: {
2001                synchronized (ActivityManagerService.this) {
2002                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2003                    if (r != null && r.app != null && r.app.thread != null) {
2004                        try {
2005                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2006                        } catch (RemoteException e) {
2007                        }
2008                    }
2009                }
2010                break;
2011            }
2012            case FINISH_BOOTING_MSG: {
2013                if (msg.arg1 != 0) {
2014                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2015                    finishBooting();
2016                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2017                }
2018                if (msg.arg2 != 0) {
2019                    enableScreenAfterBoot();
2020                }
2021                break;
2022            }
2023            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2024                try {
2025                    Locale l = (Locale) msg.obj;
2026                    IBinder service = ServiceManager.getService("mount");
2027                    IMountService mountService = IMountService.Stub.asInterface(service);
2028                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2029                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2030                } catch (RemoteException e) {
2031                    Log.e(TAG, "Error storing locale for decryption UI", e);
2032                }
2033                break;
2034            }
2035            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2036                synchronized (ActivityManagerService.this) {
2037                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2038                        try {
2039                            // Make a one-way callback to the listener
2040                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2041                        } catch (RemoteException e){
2042                            // Handled by the RemoteCallbackList
2043                        }
2044                    }
2045                    mTaskStackListeners.finishBroadcast();
2046                }
2047                break;
2048            }
2049            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2050                synchronized (ActivityManagerService.this) {
2051                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2052                        try {
2053                            // Make a one-way callback to the listener
2054                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2055                        } catch (RemoteException e){
2056                            // Handled by the RemoteCallbackList
2057                        }
2058                    }
2059                    mTaskStackListeners.finishBroadcast();
2060                }
2061                break;
2062            }
2063            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2064                synchronized (ActivityManagerService.this) {
2065                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2066                        try {
2067                            // Make a one-way callback to the listener
2068                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2069                        } catch (RemoteException e){
2070                            // Handled by the RemoteCallbackList
2071                        }
2072                    }
2073                    mTaskStackListeners.finishBroadcast();
2074                }
2075                break;
2076            }
2077            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2078                synchronized (ActivityManagerService.this) {
2079                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2080                        try {
2081                            // Make a one-way callback to the listener
2082                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2083                        } catch (RemoteException e){
2084                            // Handled by the RemoteCallbackList
2085                        }
2086                    }
2087                    mTaskStackListeners.finishBroadcast();
2088                }
2089                break;
2090            }
2091            case NOTIFY_FORCED_RESIZABLE_MSG: {
2092                synchronized (ActivityManagerService.this) {
2093                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2094                        try {
2095                            // Make a one-way callback to the listener
2096                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2097                                    (String) msg.obj, msg.arg1);
2098                        } catch (RemoteException e){
2099                            // Handled by the RemoteCallbackList
2100                        }
2101                    }
2102                    mTaskStackListeners.finishBroadcast();
2103                }
2104                break;
2105            }
2106                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2107                    synchronized (ActivityManagerService.this) {
2108                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2109                            try {
2110                                // Make a one-way callback to the listener
2111                                mTaskStackListeners.getBroadcastItem(i)
2112                                        .onActivityDismissingDockedStack();
2113                            } catch (RemoteException e){
2114                                // Handled by the RemoteCallbackList
2115                            }
2116                        }
2117                        mTaskStackListeners.finishBroadcast();
2118                    }
2119                    break;
2120                }
2121            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2122                final int uid = msg.arg1;
2123                final byte[] firstPacket = (byte[]) msg.obj;
2124
2125                synchronized (mPidsSelfLocked) {
2126                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2127                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2128                        if (p.uid == uid) {
2129                            try {
2130                                p.thread.notifyCleartextNetwork(firstPacket);
2131                            } catch (RemoteException ignored) {
2132                            }
2133                        }
2134                    }
2135                }
2136                break;
2137            }
2138            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2139                final String procName;
2140                final int uid;
2141                final long memLimit;
2142                final String reportPackage;
2143                synchronized (ActivityManagerService.this) {
2144                    procName = mMemWatchDumpProcName;
2145                    uid = mMemWatchDumpUid;
2146                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2147                    if (val == null) {
2148                        val = mMemWatchProcesses.get(procName, 0);
2149                    }
2150                    if (val != null) {
2151                        memLimit = val.first;
2152                        reportPackage = val.second;
2153                    } else {
2154                        memLimit = 0;
2155                        reportPackage = null;
2156                    }
2157                }
2158                if (procName == null) {
2159                    return;
2160                }
2161
2162                if (DEBUG_PSS) Slog.d(TAG_PSS,
2163                        "Showing dump heap notification from " + procName + "/" + uid);
2164
2165                INotificationManager inm = NotificationManager.getService();
2166                if (inm == null) {
2167                    return;
2168                }
2169
2170                String text = mContext.getString(R.string.dump_heap_notification, procName);
2171
2172
2173                Intent deleteIntent = new Intent();
2174                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2175                Intent intent = new Intent();
2176                intent.setClassName("android", DumpHeapActivity.class.getName());
2177                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2178                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2179                if (reportPackage != null) {
2180                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2181                }
2182                int userId = UserHandle.getUserId(uid);
2183                Notification notification = new Notification.Builder(mContext)
2184                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2185                        .setWhen(0)
2186                        .setOngoing(true)
2187                        .setAutoCancel(true)
2188                        .setTicker(text)
2189                        .setColor(mContext.getColor(
2190                                com.android.internal.R.color.system_notification_accent_color))
2191                        .setContentTitle(text)
2192                        .setContentText(
2193                                mContext.getText(R.string.dump_heap_notification_detail))
2194                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2195                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2196                                new UserHandle(userId)))
2197                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2198                                deleteIntent, 0, UserHandle.SYSTEM))
2199                        .build();
2200
2201                try {
2202                    int[] outId = new int[1];
2203                    inm.enqueueNotificationWithTag("android", "android", null,
2204                            R.string.dump_heap_notification,
2205                            notification, outId, userId);
2206                } catch (RuntimeException e) {
2207                    Slog.w(ActivityManagerService.TAG,
2208                            "Error showing notification for dump heap", e);
2209                } catch (RemoteException e) {
2210                }
2211            } break;
2212            case DELETE_DUMPHEAP_MSG: {
2213                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2214                        DumpHeapActivity.JAVA_URI,
2215                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2216                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2217                        UserHandle.myUserId());
2218                synchronized (ActivityManagerService.this) {
2219                    mMemWatchDumpFile = null;
2220                    mMemWatchDumpProcName = null;
2221                    mMemWatchDumpPid = -1;
2222                    mMemWatchDumpUid = -1;
2223                }
2224            } break;
2225            case FOREGROUND_PROFILE_CHANGED_MSG: {
2226                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2227            } break;
2228            case REPORT_TIME_TRACKER_MSG: {
2229                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2230                tracker.deliverResult(mContext);
2231            } break;
2232            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2233                mUserController.dispatchUserSwitchComplete(msg.arg1);
2234            } break;
2235            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2236                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2237                try {
2238                    connection.shutdown();
2239                } catch (RemoteException e) {
2240                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2241                }
2242                // Only a UiAutomation can set this flag and now that
2243                // it is finished we make sure it is reset to its default.
2244                mUserIsMonkey = false;
2245            } break;
2246            case APP_BOOST_DEACTIVATE_MSG: {
2247                synchronized(ActivityManagerService.this) {
2248                    if (mIsBoosted) {
2249                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2250                            nativeMigrateFromBoost();
2251                            mIsBoosted = false;
2252                            mBoostStartTime = 0;
2253                        } else {
2254                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2255                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2256                        }
2257                    }
2258                }
2259            } break;
2260            case IDLE_UIDS_MSG: {
2261                idleUids();
2262            } break;
2263            case LOG_STACK_STATE: {
2264                synchronized (ActivityManagerService.this) {
2265                    mStackSupervisor.logStackState();
2266                }
2267            } break;
2268            case VR_MODE_CHANGE_MSG: {
2269                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2270                final ActivityRecord r = (ActivityRecord) msg.obj;
2271                boolean vrMode;
2272                ComponentName requestedPackage;
2273                ComponentName callingPackage;
2274                int userId;
2275                synchronized (ActivityManagerService.this) {
2276                    vrMode = r.requestedVrComponent != null;
2277                    requestedPackage = r.requestedVrComponent;
2278                    userId = r.userId;
2279                    callingPackage = r.info.getComponentName();
2280                    if (mInVrMode != vrMode) {
2281                        mInVrMode = vrMode;
2282                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2283                    }
2284                }
2285                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2286            } break;
2287            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2288                final ActivityRecord r = (ActivityRecord) msg.obj;
2289                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2290                if (needsVrMode) {
2291                    VrManagerInternal vrService =
2292                            LocalServices.getService(VrManagerInternal.class);
2293                    boolean enable = msg.arg1 == 1;
2294                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2295                            r.info.getComponentName());
2296                }
2297            } break;
2298            }
2299        }
2300    };
2301
2302    static final int COLLECT_PSS_BG_MSG = 1;
2303
2304    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2305        @Override
2306        public void handleMessage(Message msg) {
2307            switch (msg.what) {
2308            case COLLECT_PSS_BG_MSG: {
2309                long start = SystemClock.uptimeMillis();
2310                MemInfoReader memInfo = null;
2311                synchronized (ActivityManagerService.this) {
2312                    if (mFullPssPending) {
2313                        mFullPssPending = false;
2314                        memInfo = new MemInfoReader();
2315                    }
2316                }
2317                if (memInfo != null) {
2318                    updateCpuStatsNow();
2319                    long nativeTotalPss = 0;
2320                    synchronized (mProcessCpuTracker) {
2321                        final int N = mProcessCpuTracker.countStats();
2322                        for (int j=0; j<N; j++) {
2323                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2324                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2325                                // This is definitely an application process; skip it.
2326                                continue;
2327                            }
2328                            synchronized (mPidsSelfLocked) {
2329                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2330                                    // This is one of our own processes; skip it.
2331                                    continue;
2332                                }
2333                            }
2334                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2335                        }
2336                    }
2337                    memInfo.readMemInfo();
2338                    synchronized (ActivityManagerService.this) {
2339                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2340                                + (SystemClock.uptimeMillis()-start) + "ms");
2341                        final long cachedKb = memInfo.getCachedSizeKb();
2342                        final long freeKb = memInfo.getFreeSizeKb();
2343                        final long zramKb = memInfo.getZramTotalSizeKb();
2344                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2345                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2346                                kernelKb*1024, nativeTotalPss*1024);
2347                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2348                                nativeTotalPss);
2349                    }
2350                }
2351
2352                int num = 0;
2353                long[] tmp = new long[2];
2354                do {
2355                    ProcessRecord proc;
2356                    int procState;
2357                    int pid;
2358                    long lastPssTime;
2359                    synchronized (ActivityManagerService.this) {
2360                        if (mPendingPssProcesses.size() <= 0) {
2361                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2362                                    "Collected PSS of " + num + " processes in "
2363                                    + (SystemClock.uptimeMillis() - start) + "ms");
2364                            mPendingPssProcesses.clear();
2365                            return;
2366                        }
2367                        proc = mPendingPssProcesses.remove(0);
2368                        procState = proc.pssProcState;
2369                        lastPssTime = proc.lastPssTime;
2370                        if (proc.thread != null && procState == proc.setProcState
2371                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2372                                        < SystemClock.uptimeMillis()) {
2373                            pid = proc.pid;
2374                        } else {
2375                            proc = null;
2376                            pid = 0;
2377                        }
2378                    }
2379                    if (proc != null) {
2380                        long pss = Debug.getPss(pid, tmp, null);
2381                        synchronized (ActivityManagerService.this) {
2382                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2383                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2384                                num++;
2385                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2386                                        SystemClock.uptimeMillis());
2387                            }
2388                        }
2389                    }
2390                } while (true);
2391            }
2392            }
2393        }
2394    };
2395
2396    public void setSystemProcess() {
2397        try {
2398            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2399            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2400            ServiceManager.addService("meminfo", new MemBinder(this));
2401            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2402            ServiceManager.addService("dbinfo", new DbBinder(this));
2403            if (MONITOR_CPU_USAGE) {
2404                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2405            }
2406            ServiceManager.addService("permission", new PermissionController(this));
2407            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2408
2409            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2410                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2411            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2412
2413            synchronized (this) {
2414                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2415                app.persistent = true;
2416                app.pid = MY_PID;
2417                app.maxAdj = ProcessList.SYSTEM_ADJ;
2418                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2419                synchronized (mPidsSelfLocked) {
2420                    mPidsSelfLocked.put(app.pid, app);
2421                }
2422                updateLruProcessLocked(app, false, null);
2423                updateOomAdjLocked();
2424            }
2425        } catch (PackageManager.NameNotFoundException e) {
2426            throw new RuntimeException(
2427                    "Unable to find android system package", e);
2428        }
2429    }
2430
2431    public void setWindowManager(WindowManagerService wm) {
2432        mWindowManager = wm;
2433        mStackSupervisor.setWindowManager(wm);
2434        mActivityStarter.setWindowManager(wm);
2435    }
2436
2437    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2438        mUsageStatsService = usageStatsManager;
2439    }
2440
2441    public void startObservingNativeCrashes() {
2442        final NativeCrashListener ncl = new NativeCrashListener(this);
2443        ncl.start();
2444    }
2445
2446    public IAppOpsService getAppOpsService() {
2447        return mAppOpsService;
2448    }
2449
2450    static class MemBinder extends Binder {
2451        ActivityManagerService mActivityManagerService;
2452        MemBinder(ActivityManagerService activityManagerService) {
2453            mActivityManagerService = activityManagerService;
2454        }
2455
2456        @Override
2457        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2458            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2459                    != PackageManager.PERMISSION_GRANTED) {
2460                pw.println("Permission Denial: can't dump meminfo from from pid="
2461                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2462                        + " without permission " + android.Manifest.permission.DUMP);
2463                return;
2464            }
2465
2466            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2467        }
2468    }
2469
2470    static class GraphicsBinder extends Binder {
2471        ActivityManagerService mActivityManagerService;
2472        GraphicsBinder(ActivityManagerService activityManagerService) {
2473            mActivityManagerService = activityManagerService;
2474        }
2475
2476        @Override
2477        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2478            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2479                    != PackageManager.PERMISSION_GRANTED) {
2480                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2481                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2482                        + " without permission " + android.Manifest.permission.DUMP);
2483                return;
2484            }
2485
2486            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2487        }
2488    }
2489
2490    static class DbBinder extends Binder {
2491        ActivityManagerService mActivityManagerService;
2492        DbBinder(ActivityManagerService activityManagerService) {
2493            mActivityManagerService = activityManagerService;
2494        }
2495
2496        @Override
2497        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2498            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2499                    != PackageManager.PERMISSION_GRANTED) {
2500                pw.println("Permission Denial: can't dump dbinfo from from pid="
2501                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2502                        + " without permission " + android.Manifest.permission.DUMP);
2503                return;
2504            }
2505
2506            mActivityManagerService.dumpDbInfo(fd, pw, args);
2507        }
2508    }
2509
2510    static class CpuBinder extends Binder {
2511        ActivityManagerService mActivityManagerService;
2512        CpuBinder(ActivityManagerService activityManagerService) {
2513            mActivityManagerService = activityManagerService;
2514        }
2515
2516        @Override
2517        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2518            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2519                    != PackageManager.PERMISSION_GRANTED) {
2520                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2521                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2522                        + " without permission " + android.Manifest.permission.DUMP);
2523                return;
2524            }
2525
2526            synchronized (mActivityManagerService.mProcessCpuTracker) {
2527                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2529                        SystemClock.uptimeMillis()));
2530            }
2531        }
2532    }
2533
2534    public static final class Lifecycle extends SystemService {
2535        private final ActivityManagerService mService;
2536
2537        public Lifecycle(Context context) {
2538            super(context);
2539            mService = new ActivityManagerService(context);
2540        }
2541
2542        @Override
2543        public void onStart() {
2544            mService.start();
2545        }
2546
2547        public ActivityManagerService getService() {
2548            return mService;
2549        }
2550    }
2551
2552    // Note: This method is invoked on the main thread but may need to attach various
2553    // handlers to other threads.  So take care to be explicit about the looper.
2554    public ActivityManagerService(Context systemContext) {
2555        mContext = systemContext;
2556        mFactoryTest = FactoryTest.getMode();
2557        mSystemThread = ActivityThread.currentActivityThread();
2558
2559        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2560
2561        mHandlerThread = new ServiceThread(TAG,
2562                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2563        mHandlerThread.start();
2564        mHandler = new MainHandler(mHandlerThread.getLooper());
2565        mUiHandler = new UiHandler();
2566
2567        /* static; one-time init here */
2568        if (sKillHandler == null) {
2569            sKillThread = new ServiceThread(TAG + ":kill",
2570                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2571            sKillThread.start();
2572            sKillHandler = new KillHandler(sKillThread.getLooper());
2573        }
2574
2575        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2576                "foreground", BROADCAST_FG_TIMEOUT, false);
2577        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2578                "background", BROADCAST_BG_TIMEOUT, true);
2579        mBroadcastQueues[0] = mFgBroadcastQueue;
2580        mBroadcastQueues[1] = mBgBroadcastQueue;
2581
2582        mServices = new ActiveServices(this);
2583        mProviderMap = new ProviderMap(this);
2584        mAppErrors = new AppErrors(mContext, this);
2585
2586        // TODO: Move creation of battery stats service outside of activity manager service.
2587        File dataDir = Environment.getDataDirectory();
2588        File systemDir = new File(dataDir, "system");
2589        systemDir.mkdirs();
2590        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2591        mBatteryStatsService.getActiveStatistics().readLocked();
2592        mBatteryStatsService.scheduleWriteToDisk();
2593        mOnBattery = DEBUG_POWER ? true
2594                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2595        mBatteryStatsService.getActiveStatistics().setCallback(this);
2596
2597        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2598
2599        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2600        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2601                new IAppOpsCallback.Stub() {
2602                    @Override public void opChanged(int op, int uid, String packageName) {
2603                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2604                            if (mAppOpsService.checkOperation(op, uid, packageName)
2605                                    != AppOpsManager.MODE_ALLOWED) {
2606                                runInBackgroundDisabled(uid);
2607                            }
2608                        }
2609                    }
2610                });
2611
2612        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2613
2614        mUserController = new UserController(this);
2615
2616        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2617            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2618
2619        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2620
2621        mConfiguration.setToDefaults();
2622        mConfiguration.setLocales(LocaleList.getDefault());
2623
2624        mConfigurationSeq = mConfiguration.seq = 1;
2625        mProcessCpuTracker.init();
2626
2627        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2628        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2629        mStackSupervisor = new ActivityStackSupervisor(this);
2630        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2631        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2632
2633        mProcessCpuThread = new Thread("CpuTracker") {
2634            @Override
2635            public void run() {
2636                while (true) {
2637                    try {
2638                        try {
2639                            synchronized(this) {
2640                                final long now = SystemClock.uptimeMillis();
2641                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2642                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2643                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2644                                //        + ", write delay=" + nextWriteDelay);
2645                                if (nextWriteDelay < nextCpuDelay) {
2646                                    nextCpuDelay = nextWriteDelay;
2647                                }
2648                                if (nextCpuDelay > 0) {
2649                                    mProcessCpuMutexFree.set(true);
2650                                    this.wait(nextCpuDelay);
2651                                }
2652                            }
2653                        } catch (InterruptedException e) {
2654                        }
2655                        updateCpuStatsNow();
2656                    } catch (Exception e) {
2657                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2658                    }
2659                }
2660            }
2661        };
2662
2663        Watchdog.getInstance().addMonitor(this);
2664        Watchdog.getInstance().addThread(mHandler);
2665    }
2666
2667    public void setSystemServiceManager(SystemServiceManager mgr) {
2668        mSystemServiceManager = mgr;
2669    }
2670
2671    public void setInstaller(Installer installer) {
2672        mInstaller = installer;
2673    }
2674
2675    private void start() {
2676        Process.removeAllProcessGroups();
2677        mProcessCpuThread.start();
2678
2679        mBatteryStatsService.publish(mContext);
2680        mAppOpsService.publish(mContext);
2681        Slog.d("AppOps", "AppOpsService published");
2682        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2683    }
2684
2685    void onUserStoppedLocked(int userId) {
2686        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2687    }
2688
2689    public void initPowerManagement() {
2690        mStackSupervisor.initPowerManagement();
2691        mBatteryStatsService.initPowerManagement();
2692        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2693        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2694        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2695        mVoiceWakeLock.setReferenceCounted(false);
2696    }
2697
2698    @Override
2699    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2700            throws RemoteException {
2701        if (code == SYSPROPS_TRANSACTION) {
2702            // We need to tell all apps about the system property change.
2703            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2704            synchronized(this) {
2705                final int NP = mProcessNames.getMap().size();
2706                for (int ip=0; ip<NP; ip++) {
2707                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2708                    final int NA = apps.size();
2709                    for (int ia=0; ia<NA; ia++) {
2710                        ProcessRecord app = apps.valueAt(ia);
2711                        if (app.thread != null) {
2712                            procs.add(app.thread.asBinder());
2713                        }
2714                    }
2715                }
2716            }
2717
2718            int N = procs.size();
2719            for (int i=0; i<N; i++) {
2720                Parcel data2 = Parcel.obtain();
2721                try {
2722                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2723                } catch (RemoteException e) {
2724                }
2725                data2.recycle();
2726            }
2727        }
2728        try {
2729            return super.onTransact(code, data, reply, flags);
2730        } catch (RuntimeException e) {
2731            // The activity manager only throws security exceptions, so let's
2732            // log all others.
2733            if (!(e instanceof SecurityException)) {
2734                Slog.wtf(TAG, "Activity Manager Crash", e);
2735            }
2736            throw e;
2737        }
2738    }
2739
2740    void updateCpuStats() {
2741        final long now = SystemClock.uptimeMillis();
2742        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2743            return;
2744        }
2745        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2746            synchronized (mProcessCpuThread) {
2747                mProcessCpuThread.notify();
2748            }
2749        }
2750    }
2751
2752    void updateCpuStatsNow() {
2753        synchronized (mProcessCpuTracker) {
2754            mProcessCpuMutexFree.set(false);
2755            final long now = SystemClock.uptimeMillis();
2756            boolean haveNewCpuStats = false;
2757
2758            if (MONITOR_CPU_USAGE &&
2759                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2760                mLastCpuTime.set(now);
2761                mProcessCpuTracker.update();
2762                if (mProcessCpuTracker.hasGoodLastStats()) {
2763                    haveNewCpuStats = true;
2764                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2765                    //Slog.i(TAG, "Total CPU usage: "
2766                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2767
2768                    // Slog the cpu usage if the property is set.
2769                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2770                        int user = mProcessCpuTracker.getLastUserTime();
2771                        int system = mProcessCpuTracker.getLastSystemTime();
2772                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2773                        int irq = mProcessCpuTracker.getLastIrqTime();
2774                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2775                        int idle = mProcessCpuTracker.getLastIdleTime();
2776
2777                        int total = user + system + iowait + irq + softIrq + idle;
2778                        if (total == 0) total = 1;
2779
2780                        EventLog.writeEvent(EventLogTags.CPU,
2781                                ((user+system+iowait+irq+softIrq) * 100) / total,
2782                                (user * 100) / total,
2783                                (system * 100) / total,
2784                                (iowait * 100) / total,
2785                                (irq * 100) / total,
2786                                (softIrq * 100) / total);
2787                    }
2788                }
2789            }
2790
2791            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2792            synchronized(bstats) {
2793                synchronized(mPidsSelfLocked) {
2794                    if (haveNewCpuStats) {
2795                        if (bstats.startAddingCpuLocked()) {
2796                            int totalUTime = 0;
2797                            int totalSTime = 0;
2798                            final int N = mProcessCpuTracker.countStats();
2799                            for (int i=0; i<N; i++) {
2800                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2801                                if (!st.working) {
2802                                    continue;
2803                                }
2804                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2805                                totalUTime += st.rel_utime;
2806                                totalSTime += st.rel_stime;
2807                                if (pr != null) {
2808                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2809                                    if (ps == null || !ps.isActive()) {
2810                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2811                                                pr.info.uid, pr.processName);
2812                                    }
2813                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2814                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2815                                } else {
2816                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2817                                    if (ps == null || !ps.isActive()) {
2818                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2819                                                bstats.mapUid(st.uid), st.name);
2820                                    }
2821                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2822                                }
2823                            }
2824                            final int userTime = mProcessCpuTracker.getLastUserTime();
2825                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2826                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2827                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2828                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2829                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2830                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2831                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2832                        }
2833                    }
2834                }
2835
2836                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2837                    mLastWriteTime = now;
2838                    mBatteryStatsService.scheduleWriteToDisk();
2839                }
2840            }
2841        }
2842    }
2843
2844    @Override
2845    public void batteryNeedsCpuUpdate() {
2846        updateCpuStatsNow();
2847    }
2848
2849    @Override
2850    public void batteryPowerChanged(boolean onBattery) {
2851        // When plugging in, update the CPU stats first before changing
2852        // the plug state.
2853        updateCpuStatsNow();
2854        synchronized (this) {
2855            synchronized(mPidsSelfLocked) {
2856                mOnBattery = DEBUG_POWER ? true : onBattery;
2857            }
2858        }
2859    }
2860
2861    @Override
2862    public void batterySendBroadcast(Intent intent) {
2863        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2864                AppOpsManager.OP_NONE, null, false, false,
2865                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2866    }
2867
2868    /**
2869     * Initialize the application bind args. These are passed to each
2870     * process when the bindApplication() IPC is sent to the process. They're
2871     * lazily setup to make sure the services are running when they're asked for.
2872     */
2873    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2874        if (mAppBindArgs == null) {
2875            mAppBindArgs = new HashMap<>();
2876
2877            // Isolated processes won't get this optimization, so that we don't
2878            // violate the rules about which services they have access to.
2879            if (!isolated) {
2880                // Setup the application init args
2881                mAppBindArgs.put("package", ServiceManager.getService("package"));
2882                mAppBindArgs.put("window", ServiceManager.getService("window"));
2883                mAppBindArgs.put(Context.ALARM_SERVICE,
2884                        ServiceManager.getService(Context.ALARM_SERVICE));
2885            }
2886        }
2887        return mAppBindArgs;
2888    }
2889
2890    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2891        if (r == null || mFocusedActivity == r) {
2892            return false;
2893        }
2894
2895        if (!r.isFocusable()) {
2896            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2897            return false;
2898        }
2899
2900        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2901
2902        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2903        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2904                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2905        mDoingSetFocusedActivity = true;
2906
2907        final ActivityRecord last = mFocusedActivity;
2908        mFocusedActivity = r;
2909        if (r.task.isApplicationTask()) {
2910            if (mCurAppTimeTracker != r.appTimeTracker) {
2911                // We are switching app tracking.  Complete the current one.
2912                if (mCurAppTimeTracker != null) {
2913                    mCurAppTimeTracker.stop();
2914                    mHandler.obtainMessage(
2915                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2916                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2917                    mCurAppTimeTracker = null;
2918                }
2919                if (r.appTimeTracker != null) {
2920                    mCurAppTimeTracker = r.appTimeTracker;
2921                    startTimeTrackingFocusedActivityLocked();
2922                }
2923            } else {
2924                startTimeTrackingFocusedActivityLocked();
2925            }
2926        } else {
2927            r.appTimeTracker = null;
2928        }
2929        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2930        // TODO: Probably not, because we don't want to resume voice on switching
2931        // back to this activity
2932        if (r.task.voiceInteractor != null) {
2933            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2934        } else {
2935            finishRunningVoiceLocked();
2936            IVoiceInteractionSession session;
2937            if (last != null && ((session = last.task.voiceSession) != null
2938                    || (session = last.voiceSession) != null)) {
2939                // We had been in a voice interaction session, but now focused has
2940                // move to something different.  Just finish the session, we can't
2941                // return to it and retain the proper state and synchronization with
2942                // the voice interaction service.
2943                finishVoiceTask(session);
2944            }
2945        }
2946        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2947            mWindowManager.setFocusedApp(r.appToken, true);
2948        }
2949        applyUpdateLockStateLocked(r);
2950        applyUpdateVrModeLocked(r);
2951        if (mFocusedActivity.userId != mLastFocusedUserId) {
2952            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2953            mHandler.obtainMessage(
2954                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2955            mLastFocusedUserId = mFocusedActivity.userId;
2956        }
2957
2958        // Log a warning if the focused app is changed during the process. This could
2959        // indicate a problem of the focus setting logic!
2960        if (mFocusedActivity != r) Slog.w(TAG,
2961                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2962        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2963
2964        EventLogTags.writeAmFocusedActivity(
2965                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2966                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2967                reason);
2968        return true;
2969    }
2970
2971    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2972        if (mFocusedActivity != goingAway) {
2973            return;
2974        }
2975
2976        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2977        if (focusedStack != null) {
2978            final ActivityRecord top = focusedStack.topActivity();
2979            if (top != null && top.userId != mLastFocusedUserId) {
2980                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2981                mHandler.sendMessage(
2982                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2983                mLastFocusedUserId = top.userId;
2984            }
2985        }
2986
2987        // Try to move focus to another activity if possible.
2988        if (setFocusedActivityLocked(
2989                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2990            return;
2991        }
2992
2993        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2994                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2995        mFocusedActivity = null;
2996        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2997    }
2998
2999    @Override
3000    public void setFocusedStack(int stackId) {
3001        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3002        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3003        final long callingId = Binder.clearCallingIdentity();
3004        try {
3005            synchronized (this) {
3006                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3007                if (stack == null) {
3008                    return;
3009                }
3010                final ActivityRecord r = stack.topRunningActivityLocked();
3011                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3012                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3013                }
3014            }
3015        } finally {
3016            Binder.restoreCallingIdentity(callingId);
3017        }
3018    }
3019
3020    @Override
3021    public void setFocusedTask(int taskId) {
3022        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3023        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3024        final long callingId = Binder.clearCallingIdentity();
3025        try {
3026            synchronized (this) {
3027                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3028                if (task == null) {
3029                    return;
3030                }
3031                final ActivityRecord r = task.topRunningActivityLocked();
3032                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3033                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3034                }
3035            }
3036        } finally {
3037            Binder.restoreCallingIdentity(callingId);
3038        }
3039    }
3040
3041    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3042    @Override
3043    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3044        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3045        synchronized (this) {
3046            if (listener != null) {
3047                mTaskStackListeners.register(listener);
3048            }
3049        }
3050    }
3051
3052    @Override
3053    public void notifyActivityDrawn(IBinder token) {
3054        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3055        synchronized (this) {
3056            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3057            if (r != null) {
3058                r.task.stack.notifyActivityDrawnLocked(r);
3059            }
3060        }
3061    }
3062
3063    final void applyUpdateLockStateLocked(ActivityRecord r) {
3064        // Modifications to the UpdateLock state are done on our handler, outside
3065        // the activity manager's locks.  The new state is determined based on the
3066        // state *now* of the relevant activity record.  The object is passed to
3067        // the handler solely for logging detail, not to be consulted/modified.
3068        final boolean nextState = r != null && r.immersive;
3069        mHandler.sendMessage(
3070                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3071    }
3072
3073    final void applyUpdateVrModeLocked(ActivityRecord r) {
3074        mHandler.sendMessage(
3075                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3076    }
3077
3078    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3079        mHandler.sendMessage(
3080                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3081    }
3082
3083    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3084        Message msg = Message.obtain();
3085        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3086        msg.obj = r.task.askedCompatMode ? null : r;
3087        mUiHandler.sendMessage(msg);
3088    }
3089
3090    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3091            String what, Object obj, ProcessRecord srcApp) {
3092        app.lastActivityTime = now;
3093
3094        if (app.activities.size() > 0) {
3095            // Don't want to touch dependent processes that are hosting activities.
3096            return index;
3097        }
3098
3099        int lrui = mLruProcesses.lastIndexOf(app);
3100        if (lrui < 0) {
3101            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3102                    + what + " " + obj + " from " + srcApp);
3103            return index;
3104        }
3105
3106        if (lrui >= index) {
3107            // Don't want to cause this to move dependent processes *back* in the
3108            // list as if they were less frequently used.
3109            return index;
3110        }
3111
3112        if (lrui >= mLruProcessActivityStart) {
3113            // Don't want to touch dependent processes that are hosting activities.
3114            return index;
3115        }
3116
3117        mLruProcesses.remove(lrui);
3118        if (index > 0) {
3119            index--;
3120        }
3121        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3122                + " in LRU list: " + app);
3123        mLruProcesses.add(index, app);
3124        return index;
3125    }
3126
3127    static void killProcessGroup(int uid, int pid) {
3128        if (sKillHandler != null) {
3129            sKillHandler.sendMessage(
3130                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3131        } else {
3132            Slog.w(TAG, "Asked to kill process group before system bringup!");
3133            Process.killProcessGroup(uid, pid);
3134        }
3135    }
3136
3137    final void removeLruProcessLocked(ProcessRecord app) {
3138        int lrui = mLruProcesses.lastIndexOf(app);
3139        if (lrui >= 0) {
3140            if (!app.killed) {
3141                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3142                Process.killProcessQuiet(app.pid);
3143                killProcessGroup(app.uid, app.pid);
3144            }
3145            if (lrui <= mLruProcessActivityStart) {
3146                mLruProcessActivityStart--;
3147            }
3148            if (lrui <= mLruProcessServiceStart) {
3149                mLruProcessServiceStart--;
3150            }
3151            mLruProcesses.remove(lrui);
3152        }
3153    }
3154
3155    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3156            ProcessRecord client) {
3157        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3158                || app.treatLikeActivity;
3159        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3160        if (!activityChange && hasActivity) {
3161            // The process has activities, so we are only allowing activity-based adjustments
3162            // to move it.  It should be kept in the front of the list with other
3163            // processes that have activities, and we don't want those to change their
3164            // order except due to activity operations.
3165            return;
3166        }
3167
3168        mLruSeq++;
3169        final long now = SystemClock.uptimeMillis();
3170        app.lastActivityTime = now;
3171
3172        // First a quick reject: if the app is already at the position we will
3173        // put it, then there is nothing to do.
3174        if (hasActivity) {
3175            final int N = mLruProcesses.size();
3176            if (N > 0 && mLruProcesses.get(N-1) == app) {
3177                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3178                return;
3179            }
3180        } else {
3181            if (mLruProcessServiceStart > 0
3182                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3183                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3184                return;
3185            }
3186        }
3187
3188        int lrui = mLruProcesses.lastIndexOf(app);
3189
3190        if (app.persistent && lrui >= 0) {
3191            // We don't care about the position of persistent processes, as long as
3192            // they are in the list.
3193            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3194            return;
3195        }
3196
3197        /* In progress: compute new position first, so we can avoid doing work
3198           if the process is not actually going to move.  Not yet working.
3199        int addIndex;
3200        int nextIndex;
3201        boolean inActivity = false, inService = false;
3202        if (hasActivity) {
3203            // Process has activities, put it at the very tipsy-top.
3204            addIndex = mLruProcesses.size();
3205            nextIndex = mLruProcessServiceStart;
3206            inActivity = true;
3207        } else if (hasService) {
3208            // Process has services, put it at the top of the service list.
3209            addIndex = mLruProcessActivityStart;
3210            nextIndex = mLruProcessServiceStart;
3211            inActivity = true;
3212            inService = true;
3213        } else  {
3214            // Process not otherwise of interest, it goes to the top of the non-service area.
3215            addIndex = mLruProcessServiceStart;
3216            if (client != null) {
3217                int clientIndex = mLruProcesses.lastIndexOf(client);
3218                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3219                        + app);
3220                if (clientIndex >= 0 && addIndex > clientIndex) {
3221                    addIndex = clientIndex;
3222                }
3223            }
3224            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3225        }
3226
3227        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3228                + mLruProcessActivityStart + "): " + app);
3229        */
3230
3231        if (lrui >= 0) {
3232            if (lrui < mLruProcessActivityStart) {
3233                mLruProcessActivityStart--;
3234            }
3235            if (lrui < mLruProcessServiceStart) {
3236                mLruProcessServiceStart--;
3237            }
3238            /*
3239            if (addIndex > lrui) {
3240                addIndex--;
3241            }
3242            if (nextIndex > lrui) {
3243                nextIndex--;
3244            }
3245            */
3246            mLruProcesses.remove(lrui);
3247        }
3248
3249        /*
3250        mLruProcesses.add(addIndex, app);
3251        if (inActivity) {
3252            mLruProcessActivityStart++;
3253        }
3254        if (inService) {
3255            mLruProcessActivityStart++;
3256        }
3257        */
3258
3259        int nextIndex;
3260        if (hasActivity) {
3261            final int N = mLruProcesses.size();
3262            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3263                // Process doesn't have activities, but has clients with
3264                // activities...  move it up, but one below the top (the top
3265                // should always have a real activity).
3266                if (DEBUG_LRU) Slog.d(TAG_LRU,
3267                        "Adding to second-top of LRU activity list: " + app);
3268                mLruProcesses.add(N - 1, app);
3269                // To keep it from spamming the LRU list (by making a bunch of clients),
3270                // we will push down any other entries owned by the app.
3271                final int uid = app.info.uid;
3272                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3273                    ProcessRecord subProc = mLruProcesses.get(i);
3274                    if (subProc.info.uid == uid) {
3275                        // We want to push this one down the list.  If the process after
3276                        // it is for the same uid, however, don't do so, because we don't
3277                        // want them internally to be re-ordered.
3278                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3279                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3280                                    "Pushing uid " + uid + " swapping at " + i + ": "
3281                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3282                            ProcessRecord tmp = mLruProcesses.get(i);
3283                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3284                            mLruProcesses.set(i - 1, tmp);
3285                            i--;
3286                        }
3287                    } else {
3288                        // A gap, we can stop here.
3289                        break;
3290                    }
3291                }
3292            } else {
3293                // Process has activities, put it at the very tipsy-top.
3294                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3295                mLruProcesses.add(app);
3296            }
3297            nextIndex = mLruProcessServiceStart;
3298        } else if (hasService) {
3299            // Process has services, put it at the top of the service list.
3300            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3301            mLruProcesses.add(mLruProcessActivityStart, app);
3302            nextIndex = mLruProcessServiceStart;
3303            mLruProcessActivityStart++;
3304        } else  {
3305            // Process not otherwise of interest, it goes to the top of the non-service area.
3306            int index = mLruProcessServiceStart;
3307            if (client != null) {
3308                // If there is a client, don't allow the process to be moved up higher
3309                // in the list than that client.
3310                int clientIndex = mLruProcesses.lastIndexOf(client);
3311                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3312                        + " when updating " + app);
3313                if (clientIndex <= lrui) {
3314                    // Don't allow the client index restriction to push it down farther in the
3315                    // list than it already is.
3316                    clientIndex = lrui;
3317                }
3318                if (clientIndex >= 0 && index > clientIndex) {
3319                    index = clientIndex;
3320                }
3321            }
3322            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3323            mLruProcesses.add(index, app);
3324            nextIndex = index-1;
3325            mLruProcessActivityStart++;
3326            mLruProcessServiceStart++;
3327        }
3328
3329        // If the app is currently using a content provider or service,
3330        // bump those processes as well.
3331        for (int j=app.connections.size()-1; j>=0; j--) {
3332            ConnectionRecord cr = app.connections.valueAt(j);
3333            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3334                    && cr.binding.service.app != null
3335                    && cr.binding.service.app.lruSeq != mLruSeq
3336                    && !cr.binding.service.app.persistent) {
3337                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3338                        "service connection", cr, app);
3339            }
3340        }
3341        for (int j=app.conProviders.size()-1; j>=0; j--) {
3342            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3343            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3344                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3345                        "provider reference", cpr, app);
3346            }
3347        }
3348    }
3349
3350    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3351        if (uid == Process.SYSTEM_UID) {
3352            // The system gets to run in any process.  If there are multiple
3353            // processes with the same uid, just pick the first (this
3354            // should never happen).
3355            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3356            if (procs == null) return null;
3357            final int procCount = procs.size();
3358            for (int i = 0; i < procCount; i++) {
3359                final int procUid = procs.keyAt(i);
3360                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3361                    // Don't use an app process or different user process for system component.
3362                    continue;
3363                }
3364                return procs.valueAt(i);
3365            }
3366        }
3367        ProcessRecord proc = mProcessNames.get(processName, uid);
3368        if (false && proc != null && !keepIfLarge
3369                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3370                && proc.lastCachedPss >= 4000) {
3371            // Turn this condition on to cause killing to happen regularly, for testing.
3372            if (proc.baseProcessTracker != null) {
3373                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3374            }
3375            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3376        } else if (proc != null && !keepIfLarge
3377                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3378                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3379            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3380            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3381                if (proc.baseProcessTracker != null) {
3382                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3383                }
3384                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3385            }
3386        }
3387        return proc;
3388    }
3389
3390    void notifyPackageUse(String packageName, int reason) {
3391        IPackageManager pm = AppGlobals.getPackageManager();
3392        try {
3393            pm.notifyPackageUse(packageName, reason);
3394        } catch (RemoteException e) {
3395        }
3396    }
3397
3398    boolean isNextTransitionForward() {
3399        int transit = mWindowManager.getPendingAppTransition();
3400        return transit == TRANSIT_ACTIVITY_OPEN
3401                || transit == TRANSIT_TASK_OPEN
3402                || transit == TRANSIT_TASK_TO_FRONT;
3403    }
3404
3405    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3406            String processName, String abiOverride, int uid, Runnable crashHandler) {
3407        synchronized(this) {
3408            ApplicationInfo info = new ApplicationInfo();
3409            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3410            // For isolated processes, the former contains the parent's uid and the latter the
3411            // actual uid of the isolated process.
3412            // In the special case introduced by this method (which is, starting an isolated
3413            // process directly from the SystemServer without an actual parent app process) the
3414            // closest thing to a parent's uid is SYSTEM_UID.
3415            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3416            // the |isolated| logic in the ProcessRecord constructor.
3417            info.uid = Process.SYSTEM_UID;
3418            info.processName = processName;
3419            info.className = entryPoint;
3420            info.packageName = "android";
3421            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3422                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3423                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3424                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3425                    crashHandler);
3426            return proc != null ? proc.pid : 0;
3427        }
3428    }
3429
3430    final ProcessRecord startProcessLocked(String processName,
3431            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3432            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3433            boolean isolated, boolean keepIfLarge) {
3434        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3435                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3436                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3437                null /* crashHandler */);
3438    }
3439
3440    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3441            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3442            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3443            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3444        long startTime = SystemClock.elapsedRealtime();
3445        ProcessRecord app;
3446        if (!isolated) {
3447            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3448            checkTime(startTime, "startProcess: after getProcessRecord");
3449
3450            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3451                // If we are in the background, then check to see if this process
3452                // is bad.  If so, we will just silently fail.
3453                if (mAppErrors.isBadProcessLocked(info)) {
3454                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3455                            + "/" + info.processName);
3456                    return null;
3457                }
3458            } else {
3459                // When the user is explicitly starting a process, then clear its
3460                // crash count so that we won't make it bad until they see at
3461                // least one crash dialog again, and make the process good again
3462                // if it had been bad.
3463                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3464                        + "/" + info.processName);
3465                mAppErrors.resetProcessCrashTimeLocked(info);
3466                if (mAppErrors.isBadProcessLocked(info)) {
3467                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3468                            UserHandle.getUserId(info.uid), info.uid,
3469                            info.processName);
3470                    mAppErrors.clearBadProcessLocked(info);
3471                    if (app != null) {
3472                        app.bad = false;
3473                    }
3474                }
3475            }
3476        } else {
3477            // If this is an isolated process, it can't re-use an existing process.
3478            app = null;
3479        }
3480
3481        // app launch boost for big.little configurations
3482        // use cpusets to migrate freshly launched tasks to big cores
3483        synchronized(ActivityManagerService.this) {
3484            nativeMigrateToBoost();
3485            mIsBoosted = true;
3486            mBoostStartTime = SystemClock.uptimeMillis();
3487            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3488            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3489        }
3490
3491        // We don't have to do anything more if:
3492        // (1) There is an existing application record; and
3493        // (2) The caller doesn't think it is dead, OR there is no thread
3494        //     object attached to it so we know it couldn't have crashed; and
3495        // (3) There is a pid assigned to it, so it is either starting or
3496        //     already running.
3497        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3498                + " app=" + app + " knownToBeDead=" + knownToBeDead
3499                + " thread=" + (app != null ? app.thread : null)
3500                + " pid=" + (app != null ? app.pid : -1));
3501        if (app != null && app.pid > 0) {
3502            if (!knownToBeDead || app.thread == null) {
3503                // We already have the app running, or are waiting for it to
3504                // come up (we have a pid but not yet its thread), so keep it.
3505                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
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: done, added package to proc");
3509                return app;
3510            }
3511
3512            // An application record is attached to a previous process,
3513            // clean it up now.
3514            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3515            checkTime(startTime, "startProcess: bad proc running, killing");
3516            killProcessGroup(app.uid, app.pid);
3517            handleAppDiedLocked(app, true, true);
3518            checkTime(startTime, "startProcess: done killing old proc");
3519        }
3520
3521        String hostingNameStr = hostingName != null
3522                ? hostingName.flattenToShortString() : null;
3523
3524        if (app == null) {
3525            checkTime(startTime, "startProcess: creating new process record");
3526            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3527            if (app == null) {
3528                Slog.w(TAG, "Failed making new process record for "
3529                        + processName + "/" + info.uid + " isolated=" + isolated);
3530                return null;
3531            }
3532            app.crashHandler = crashHandler;
3533            checkTime(startTime, "startProcess: done creating new process record");
3534        } else {
3535            // If this is a new package in the process, add the package to the list
3536            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3537            checkTime(startTime, "startProcess: added package to existing proc");
3538        }
3539
3540        // If the system is not ready yet, then hold off on starting this
3541        // process until it is.
3542        if (!mProcessesReady
3543                && !isAllowedWhileBooting(info)
3544                && !allowWhileBooting) {
3545            if (!mProcessesOnHold.contains(app)) {
3546                mProcessesOnHold.add(app);
3547            }
3548            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3549                    "System not ready, putting on hold: " + app);
3550            checkTime(startTime, "startProcess: returning with proc on hold");
3551            return app;
3552        }
3553
3554        checkTime(startTime, "startProcess: stepping in to startProcess");
3555        startProcessLocked(
3556                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3557        checkTime(startTime, "startProcess: done starting proc!");
3558        return (app.pid != 0) ? app : null;
3559    }
3560
3561    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3562        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3563    }
3564
3565    private final void startProcessLocked(ProcessRecord app,
3566            String hostingType, String hostingNameStr) {
3567        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3568                null /* entryPoint */, null /* entryPointArgs */);
3569    }
3570
3571    private final void startProcessLocked(ProcessRecord app, String hostingType,
3572            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3573        long startTime = SystemClock.elapsedRealtime();
3574        if (app.pid > 0 && app.pid != MY_PID) {
3575            checkTime(startTime, "startProcess: removing from pids map");
3576            synchronized (mPidsSelfLocked) {
3577                mPidsSelfLocked.remove(app.pid);
3578                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3579            }
3580            checkTime(startTime, "startProcess: done removing from pids map");
3581            app.setPid(0);
3582        }
3583
3584        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3585                "startProcessLocked removing on hold: " + app);
3586        mProcessesOnHold.remove(app);
3587
3588        checkTime(startTime, "startProcess: starting to update cpu stats");
3589        updateCpuStats();
3590        checkTime(startTime, "startProcess: done updating cpu stats");
3591
3592        try {
3593            try {
3594                final int userId = UserHandle.getUserId(app.uid);
3595                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3596            } catch (RemoteException e) {
3597                throw e.rethrowAsRuntimeException();
3598            }
3599
3600            int uid = app.uid;
3601            int[] gids = null;
3602            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3603            if (!app.isolated) {
3604                int[] permGids = null;
3605                try {
3606                    checkTime(startTime, "startProcess: getting gids from package manager");
3607                    final IPackageManager pm = AppGlobals.getPackageManager();
3608                    permGids = pm.getPackageGids(app.info.packageName,
3609                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3610                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3611                            MountServiceInternal.class);
3612                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3613                            app.info.packageName);
3614                } catch (RemoteException e) {
3615                    throw e.rethrowAsRuntimeException();
3616                }
3617
3618                /*
3619                 * Add shared application and profile GIDs so applications can share some
3620                 * resources like shared libraries and access user-wide resources
3621                 */
3622                if (ArrayUtils.isEmpty(permGids)) {
3623                    gids = new int[2];
3624                } else {
3625                    gids = new int[permGids.length + 2];
3626                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3627                }
3628                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3629                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3630            }
3631            checkTime(startTime, "startProcess: building args");
3632            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3633                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3634                        && mTopComponent != null
3635                        && app.processName.equals(mTopComponent.getPackageName())) {
3636                    uid = 0;
3637                }
3638                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3639                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3640                    uid = 0;
3641                }
3642            }
3643            int debugFlags = 0;
3644            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3645                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3646                // Also turn on CheckJNI for debuggable apps. It's quite
3647                // awkward to turn on otherwise.
3648                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3649            }
3650            // Run the app in safe mode if its manifest requests so or the
3651            // system is booted in safe mode.
3652            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3653                mSafeMode == true) {
3654                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3655            }
3656            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3657                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3658            }
3659            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3660            if ("true".equals(genDebugInfoProperty)) {
3661                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3662            }
3663            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3664                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3665            }
3666            if ("1".equals(SystemProperties.get("debug.assert"))) {
3667                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3668            }
3669            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3670                // Enable all debug flags required by the native debugger.
3671                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3672                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3673                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3674                mNativeDebuggingApp = null;
3675            }
3676
3677            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3678            if (requiredAbi == null) {
3679                requiredAbi = Build.SUPPORTED_ABIS[0];
3680            }
3681
3682            String instructionSet = null;
3683            if (app.info.primaryCpuAbi != null) {
3684                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3685            }
3686
3687            app.gids = gids;
3688            app.requiredAbi = requiredAbi;
3689            app.instructionSet = instructionSet;
3690
3691            // Start the process.  It will either succeed and return a result containing
3692            // the PID of the new process, or else throw a RuntimeException.
3693            boolean isActivityProcess = (entryPoint == null);
3694            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3695            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3696                    app.processName);
3697            checkTime(startTime, "startProcess: asking zygote to start proc");
3698            Process.ProcessStartResult startResult = Process.start(entryPoint,
3699                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3700                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3701                    app.info.dataDir, entryPointArgs);
3702            checkTime(startTime, "startProcess: returned from zygote!");
3703            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3704
3705            if (app.isolated) {
3706                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3707            }
3708            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3709            checkTime(startTime, "startProcess: done updating battery stats");
3710
3711            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3712                    UserHandle.getUserId(uid), startResult.pid, uid,
3713                    app.processName, hostingType,
3714                    hostingNameStr != null ? hostingNameStr : "");
3715
3716            try {
3717                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3718                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3719            } catch (RemoteException ex) {
3720                // Ignore
3721            }
3722
3723            if (app.persistent) {
3724                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3725            }
3726
3727            checkTime(startTime, "startProcess: building log message");
3728            StringBuilder buf = mStringBuilder;
3729            buf.setLength(0);
3730            buf.append("Start proc ");
3731            buf.append(startResult.pid);
3732            buf.append(':');
3733            buf.append(app.processName);
3734            buf.append('/');
3735            UserHandle.formatUid(buf, uid);
3736            if (!isActivityProcess) {
3737                buf.append(" [");
3738                buf.append(entryPoint);
3739                buf.append("]");
3740            }
3741            buf.append(" for ");
3742            buf.append(hostingType);
3743            if (hostingNameStr != null) {
3744                buf.append(" ");
3745                buf.append(hostingNameStr);
3746            }
3747            Slog.i(TAG, buf.toString());
3748            app.setPid(startResult.pid);
3749            app.usingWrapper = startResult.usingWrapper;
3750            app.removed = false;
3751            app.killed = false;
3752            app.killedByAm = false;
3753            checkTime(startTime, "startProcess: starting to update pids map");
3754            synchronized (mPidsSelfLocked) {
3755                this.mPidsSelfLocked.put(startResult.pid, app);
3756                if (isActivityProcess) {
3757                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3758                    msg.obj = app;
3759                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3760                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3761                }
3762            }
3763            checkTime(startTime, "startProcess: done updating pids map");
3764        } catch (RuntimeException e) {
3765            Slog.e(TAG, "Failure starting process " + app.processName, e);
3766
3767            // Something went very wrong while trying to start this process; one
3768            // common case is when the package is frozen due to an active
3769            // upgrade. To recover, clean up any active bookkeeping related to
3770            // starting this process. (We already invoked this method once when
3771            // the package was initially frozen through KILL_APPLICATION_MSG, so
3772            // it doesn't hurt to use it again.)
3773            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3774                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3775        }
3776    }
3777
3778    void updateUsageStats(ActivityRecord component, boolean resumed) {
3779        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3780                "updateUsageStats: comp=" + component + "res=" + resumed);
3781        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3782        if (resumed) {
3783            if (mUsageStatsService != null) {
3784                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3785                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3786            }
3787            synchronized (stats) {
3788                stats.noteActivityResumedLocked(component.app.uid);
3789            }
3790        } else {
3791            if (mUsageStatsService != null) {
3792                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3793                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3794            }
3795            synchronized (stats) {
3796                stats.noteActivityPausedLocked(component.app.uid);
3797            }
3798        }
3799    }
3800
3801    Intent getHomeIntent() {
3802        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3803        intent.setComponent(mTopComponent);
3804        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3805        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3806            intent.addCategory(Intent.CATEGORY_HOME);
3807        }
3808        return intent;
3809    }
3810
3811    boolean startHomeActivityLocked(int userId, String reason) {
3812        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3813                && mTopAction == null) {
3814            // We are running in factory test mode, but unable to find
3815            // the factory test app, so just sit around displaying the
3816            // error message and don't try to start anything.
3817            return false;
3818        }
3819        Intent intent = getHomeIntent();
3820        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3821        if (aInfo != null) {
3822            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3823            // Don't do this if the home app is currently being
3824            // instrumented.
3825            aInfo = new ActivityInfo(aInfo);
3826            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3827            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3828                    aInfo.applicationInfo.uid, true);
3829            if (app == null || app.instrumentationClass == null) {
3830                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3831                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3832            }
3833        } else {
3834            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3835        }
3836
3837        return true;
3838    }
3839
3840    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3841        ActivityInfo ai = null;
3842        ComponentName comp = intent.getComponent();
3843        try {
3844            if (comp != null) {
3845                // Factory test.
3846                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3847            } else {
3848                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3849                        intent,
3850                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3851                        flags, userId);
3852
3853                if (info != null) {
3854                    ai = info.activityInfo;
3855                }
3856            }
3857        } catch (RemoteException e) {
3858            // ignore
3859        }
3860
3861        return ai;
3862    }
3863
3864    /**
3865     * Starts the "new version setup screen" if appropriate.
3866     */
3867    void startSetupActivityLocked() {
3868        // Only do this once per boot.
3869        if (mCheckedForSetup) {
3870            return;
3871        }
3872
3873        // We will show this screen if the current one is a different
3874        // version than the last one shown, and we are not running in
3875        // low-level factory test mode.
3876        final ContentResolver resolver = mContext.getContentResolver();
3877        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3878                Settings.Global.getInt(resolver,
3879                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3880            mCheckedForSetup = true;
3881
3882            // See if we should be showing the platform update setup UI.
3883            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3884            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3885                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3886            if (!ris.isEmpty()) {
3887                final ResolveInfo ri = ris.get(0);
3888                String vers = ri.activityInfo.metaData != null
3889                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3890                        : null;
3891                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3892                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3893                            Intent.METADATA_SETUP_VERSION);
3894                }
3895                String lastVers = Settings.Secure.getString(
3896                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3897                if (vers != null && !vers.equals(lastVers)) {
3898                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3899                    intent.setComponent(new ComponentName(
3900                            ri.activityInfo.packageName, ri.activityInfo.name));
3901                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3902                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3903                            null, 0, 0, 0, null, false, false, null, null, null);
3904                }
3905            }
3906        }
3907    }
3908
3909    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3910        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3911    }
3912
3913    void enforceNotIsolatedCaller(String caller) {
3914        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3915            throw new SecurityException("Isolated process not allowed to call " + caller);
3916        }
3917    }
3918
3919    void enforceShellRestriction(String restriction, int userHandle) {
3920        if (Binder.getCallingUid() == Process.SHELL_UID) {
3921            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3922                throw new SecurityException("Shell does not have permission to access user "
3923                        + userHandle);
3924            }
3925        }
3926    }
3927
3928    @Override
3929    public int getFrontActivityScreenCompatMode() {
3930        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3931        synchronized (this) {
3932            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3933        }
3934    }
3935
3936    @Override
3937    public void setFrontActivityScreenCompatMode(int mode) {
3938        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3939                "setFrontActivityScreenCompatMode");
3940        synchronized (this) {
3941            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3942        }
3943    }
3944
3945    @Override
3946    public int getPackageScreenCompatMode(String packageName) {
3947        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3948        synchronized (this) {
3949            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3950        }
3951    }
3952
3953    @Override
3954    public void setPackageScreenCompatMode(String packageName, int mode) {
3955        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3956                "setPackageScreenCompatMode");
3957        synchronized (this) {
3958            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3959        }
3960    }
3961
3962    @Override
3963    public boolean getPackageAskScreenCompat(String packageName) {
3964        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3965        synchronized (this) {
3966            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3967        }
3968    }
3969
3970    @Override
3971    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3973                "setPackageAskScreenCompat");
3974        synchronized (this) {
3975            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3976        }
3977    }
3978
3979    private boolean hasUsageStatsPermission(String callingPackage) {
3980        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3981                Binder.getCallingUid(), callingPackage);
3982        if (mode == AppOpsManager.MODE_DEFAULT) {
3983            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3984                    == PackageManager.PERMISSION_GRANTED;
3985        }
3986        return mode == AppOpsManager.MODE_ALLOWED;
3987    }
3988
3989    @Override
3990    public int getPackageProcessState(String packageName, String callingPackage) {
3991        if (!hasUsageStatsPermission(callingPackage)) {
3992            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3993                    "getPackageProcessState");
3994        }
3995
3996        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3997        synchronized (this) {
3998            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3999                final ProcessRecord proc = mLruProcesses.get(i);
4000                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4001                        || procState > proc.setProcState) {
4002                    boolean found = false;
4003                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4004                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4005                            procState = proc.setProcState;
4006                            found = true;
4007                        }
4008                    }
4009                    if (proc.pkgDeps != null && !found) {
4010                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4011                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4012                                procState = proc.setProcState;
4013                                break;
4014                            }
4015                        }
4016                    }
4017                }
4018            }
4019        }
4020        return procState;
4021    }
4022
4023    @Override
4024    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4025        synchronized (this) {
4026            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4027            if (app == null) {
4028                return false;
4029            }
4030            if (app.trimMemoryLevel < level && app.thread != null &&
4031                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4032                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4033                try {
4034                    app.thread.scheduleTrimMemory(level);
4035                    app.trimMemoryLevel = level;
4036                    return true;
4037                } catch (RemoteException e) {
4038                    // Fallthrough to failure case.
4039                }
4040            }
4041        }
4042        return false;
4043    }
4044
4045    private void dispatchProcessesChanged() {
4046        int N;
4047        synchronized (this) {
4048            N = mPendingProcessChanges.size();
4049            if (mActiveProcessChanges.length < N) {
4050                mActiveProcessChanges = new ProcessChangeItem[N];
4051            }
4052            mPendingProcessChanges.toArray(mActiveProcessChanges);
4053            mPendingProcessChanges.clear();
4054            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4055                    "*** Delivering " + N + " process changes");
4056        }
4057
4058        int i = mProcessObservers.beginBroadcast();
4059        while (i > 0) {
4060            i--;
4061            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4062            if (observer != null) {
4063                try {
4064                    for (int j=0; j<N; j++) {
4065                        ProcessChangeItem item = mActiveProcessChanges[j];
4066                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4067                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4068                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4069                                    + item.uid + ": " + item.foregroundActivities);
4070                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4071                                    item.foregroundActivities);
4072                        }
4073                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4074                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4075                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4076                                    + ": " + item.processState);
4077                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4078                        }
4079                    }
4080                } catch (RemoteException e) {
4081                }
4082            }
4083        }
4084        mProcessObservers.finishBroadcast();
4085
4086        synchronized (this) {
4087            for (int j=0; j<N; j++) {
4088                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4089            }
4090        }
4091    }
4092
4093    private void dispatchProcessDied(int pid, int uid) {
4094        int i = mProcessObservers.beginBroadcast();
4095        while (i > 0) {
4096            i--;
4097            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4098            if (observer != null) {
4099                try {
4100                    observer.onProcessDied(pid, uid);
4101                } catch (RemoteException e) {
4102                }
4103            }
4104        }
4105        mProcessObservers.finishBroadcast();
4106    }
4107
4108    private void dispatchUidsChanged() {
4109        int N;
4110        synchronized (this) {
4111            N = mPendingUidChanges.size();
4112            if (mActiveUidChanges.length < N) {
4113                mActiveUidChanges = new UidRecord.ChangeItem[N];
4114            }
4115            for (int i=0; i<N; i++) {
4116                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4117                mActiveUidChanges[i] = change;
4118                if (change.uidRecord != null) {
4119                    change.uidRecord.pendingChange = null;
4120                    change.uidRecord = null;
4121                }
4122            }
4123            mPendingUidChanges.clear();
4124            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4125                    "*** Delivering " + N + " uid changes");
4126        }
4127
4128        if (mLocalPowerManager != null) {
4129            for (int j=0; j<N; j++) {
4130                UidRecord.ChangeItem item = mActiveUidChanges[j];
4131                if (item.change == UidRecord.CHANGE_GONE
4132                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4133                    mLocalPowerManager.uidGone(item.uid);
4134                } else {
4135                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4136                }
4137            }
4138        }
4139
4140        int i = mUidObservers.beginBroadcast();
4141        while (i > 0) {
4142            i--;
4143            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4144            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4145            if (observer != null) {
4146                try {
4147                    for (int j=0; j<N; j++) {
4148                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4149                        final int change = item.change;
4150                        UidRecord validateUid = null;
4151                        if (VALIDATE_UID_STATES && i == 0) {
4152                            validateUid = mValidateUids.get(item.uid);
4153                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4154                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4155                                validateUid = new UidRecord(item.uid);
4156                                mValidateUids.put(item.uid, validateUid);
4157                            }
4158                        }
4159                        if (change == UidRecord.CHANGE_IDLE
4160                                || change == UidRecord.CHANGE_GONE_IDLE) {
4161                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4162                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4163                                        "UID idle uid=" + item.uid);
4164                                observer.onUidIdle(item.uid);
4165                            }
4166                            if (VALIDATE_UID_STATES && i == 0) {
4167                                if (validateUid != null) {
4168                                    validateUid.idle = true;
4169                                }
4170                            }
4171                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4172                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4173                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4174                                        "UID active uid=" + item.uid);
4175                                observer.onUidActive(item.uid);
4176                            }
4177                            if (VALIDATE_UID_STATES && i == 0) {
4178                                validateUid.idle = false;
4179                            }
4180                        }
4181                        if (change == UidRecord.CHANGE_GONE
4182                                || change == UidRecord.CHANGE_GONE_IDLE) {
4183                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4184                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4185                                        "UID gone uid=" + item.uid);
4186                                observer.onUidGone(item.uid);
4187                            }
4188                            if (VALIDATE_UID_STATES && i == 0) {
4189                                if (validateUid != null) {
4190                                    mValidateUids.remove(item.uid);
4191                                }
4192                            }
4193                        } else {
4194                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4195                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4196                                        "UID CHANGED uid=" + item.uid
4197                                                + ": " + item.processState);
4198                                observer.onUidStateChanged(item.uid, item.processState);
4199                            }
4200                            if (VALIDATE_UID_STATES && i == 0) {
4201                                validateUid.curProcState = validateUid.setProcState
4202                                        = item.processState;
4203                            }
4204                        }
4205                    }
4206                } catch (RemoteException e) {
4207                }
4208            }
4209        }
4210        mUidObservers.finishBroadcast();
4211
4212        synchronized (this) {
4213            for (int j=0; j<N; j++) {
4214                mAvailUidChanges.add(mActiveUidChanges[j]);
4215            }
4216        }
4217    }
4218
4219    @Override
4220    public final int startActivity(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4223        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4224                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4225                UserHandle.getCallingUserId());
4226    }
4227
4228    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4229        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4230        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4231                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4232                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4233
4234        // TODO: Switch to user app stacks here.
4235        String mimeType = intent.getType();
4236        final Uri data = intent.getData();
4237        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4238            mimeType = getProviderMimeType(data, userId);
4239        }
4240        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4241
4242        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4243        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4244                null, 0, 0, null, null, null, null, false, userId, container, null);
4245    }
4246
4247    @Override
4248    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4249            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4250            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4251        enforceNotIsolatedCaller("startActivity");
4252        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4253                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4254        // TODO: Switch to user app stacks here.
4255        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4256                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4257                profilerInfo, null, null, bOptions, false, userId, null, null);
4258    }
4259
4260    @Override
4261    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4262            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4263            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4264            int userId) {
4265
4266        // This is very dangerous -- it allows you to perform a start activity (including
4267        // permission grants) as any app that may launch one of your own activities.  So
4268        // we will only allow this to be done from activities that are part of the core framework,
4269        // and then only when they are running as the system.
4270        final ActivityRecord sourceRecord;
4271        final int targetUid;
4272        final String targetPackage;
4273        synchronized (this) {
4274            if (resultTo == null) {
4275                throw new SecurityException("Must be called from an activity");
4276            }
4277            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4278            if (sourceRecord == null) {
4279                throw new SecurityException("Called with bad activity token: " + resultTo);
4280            }
4281            if (!sourceRecord.info.packageName.equals("android")) {
4282                throw new SecurityException(
4283                        "Must be called from an activity that is declared in the android package");
4284            }
4285            if (sourceRecord.app == null) {
4286                throw new SecurityException("Called without a process attached to activity");
4287            }
4288            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4289                // This is still okay, as long as this activity is running under the
4290                // uid of the original calling activity.
4291                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4292                    throw new SecurityException(
4293                            "Calling activity in uid " + sourceRecord.app.uid
4294                                    + " must be system uid or original calling uid "
4295                                    + sourceRecord.launchedFromUid);
4296                }
4297            }
4298            if (ignoreTargetSecurity) {
4299                if (intent.getComponent() == null) {
4300                    throw new SecurityException(
4301                            "Component must be specified with ignoreTargetSecurity");
4302                }
4303                if (intent.getSelector() != null) {
4304                    throw new SecurityException(
4305                            "Selector not allowed with ignoreTargetSecurity");
4306                }
4307            }
4308            targetUid = sourceRecord.launchedFromUid;
4309            targetPackage = sourceRecord.launchedFromPackage;
4310        }
4311
4312        if (userId == UserHandle.USER_NULL) {
4313            userId = UserHandle.getUserId(sourceRecord.app.uid);
4314        }
4315
4316        // TODO: Switch to user app stacks here.
4317        try {
4318            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4319                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4320                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4321            return ret;
4322        } catch (SecurityException e) {
4323            // XXX need to figure out how to propagate to original app.
4324            // A SecurityException here is generally actually a fault of the original
4325            // calling activity (such as a fairly granting permissions), so propagate it
4326            // back to them.
4327            /*
4328            StringBuilder msg = new StringBuilder();
4329            msg.append("While launching");
4330            msg.append(intent.toString());
4331            msg.append(": ");
4332            msg.append(e.getMessage());
4333            */
4334            throw e;
4335        }
4336    }
4337
4338    @Override
4339    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4340            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4341            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4342        enforceNotIsolatedCaller("startActivityAndWait");
4343        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4344                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4345        WaitResult res = new WaitResult();
4346        // TODO: Switch to user app stacks here.
4347        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4348                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4349                bOptions, false, userId, null, null);
4350        return res;
4351    }
4352
4353    @Override
4354    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4355            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4356            int startFlags, Configuration config, Bundle bOptions, int userId) {
4357        enforceNotIsolatedCaller("startActivityWithConfig");
4358        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4359                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4360        // TODO: Switch to user app stacks here.
4361        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4362                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4363                null, null, config, bOptions, false, userId, null, null);
4364        return ret;
4365    }
4366
4367    @Override
4368    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4369            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4370            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4371            throws TransactionTooLargeException {
4372        enforceNotIsolatedCaller("startActivityIntentSender");
4373        // Refuse possible leaked file descriptors
4374        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4375            throw new IllegalArgumentException("File descriptors passed in Intent");
4376        }
4377
4378        IIntentSender sender = intent.getTarget();
4379        if (!(sender instanceof PendingIntentRecord)) {
4380            throw new IllegalArgumentException("Bad PendingIntent object");
4381        }
4382
4383        PendingIntentRecord pir = (PendingIntentRecord)sender;
4384
4385        synchronized (this) {
4386            // If this is coming from the currently resumed activity, it is
4387            // effectively saying that app switches are allowed at this point.
4388            final ActivityStack stack = getFocusedStack();
4389            if (stack.mResumedActivity != null &&
4390                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4391                mAppSwitchesAllowedTime = 0;
4392            }
4393        }
4394        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4395                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4396        return ret;
4397    }
4398
4399    @Override
4400    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4401            Intent intent, String resolvedType, IVoiceInteractionSession session,
4402            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4403            Bundle bOptions, int userId) {
4404        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4405                != PackageManager.PERMISSION_GRANTED) {
4406            String msg = "Permission Denial: startVoiceActivity() from pid="
4407                    + Binder.getCallingPid()
4408                    + ", uid=" + Binder.getCallingUid()
4409                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4410            Slog.w(TAG, msg);
4411            throw new SecurityException(msg);
4412        }
4413        if (session == null || interactor == null) {
4414            throw new NullPointerException("null session or interactor");
4415        }
4416        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4417                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4418        // TODO: Switch to user app stacks here.
4419        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4420                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4421                null, bOptions, false, userId, null, null);
4422    }
4423
4424    @Override
4425    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4426            throws RemoteException {
4427        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4428        synchronized (this) {
4429            ActivityRecord activity = getFocusedStack().topActivity();
4430            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4431                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4432            }
4433            if (mRunningVoice != null || activity.task.voiceSession != null
4434                    || activity.voiceSession != null) {
4435                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4436                return;
4437            }
4438            if (activity.pendingVoiceInteractionStart) {
4439                Slog.w(TAG, "Pending start of voice interaction already.");
4440                return;
4441            }
4442            activity.pendingVoiceInteractionStart = true;
4443        }
4444        LocalServices.getService(VoiceInteractionManagerInternal.class)
4445                .startLocalVoiceInteraction(callingActivity, options);
4446    }
4447
4448    @Override
4449    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4450        LocalServices.getService(VoiceInteractionManagerInternal.class)
4451                .stopLocalVoiceInteraction(callingActivity);
4452    }
4453
4454    @Override
4455    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4456        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4457                .supportsLocalVoiceInteraction();
4458    }
4459
4460    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4461            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4462        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4463        if (activityToCallback == null) return;
4464        activityToCallback.setVoiceSessionLocked(voiceSession);
4465
4466        // Inform the activity
4467        try {
4468            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4469                    voiceInteractor);
4470            long token = Binder.clearCallingIdentity();
4471            try {
4472                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4473            } finally {
4474                Binder.restoreCallingIdentity(token);
4475            }
4476            // TODO: VI Should we cache the activity so that it's easier to find later
4477            // rather than scan through all the stacks and activities?
4478        } catch (RemoteException re) {
4479            activityToCallback.clearVoiceSessionLocked();
4480            // TODO: VI Should this terminate the voice session?
4481        }
4482    }
4483
4484    @Override
4485    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4486        synchronized (this) {
4487            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4488                if (keepAwake) {
4489                    mVoiceWakeLock.acquire();
4490                } else {
4491                    mVoiceWakeLock.release();
4492                }
4493            }
4494        }
4495    }
4496
4497    @Override
4498    public boolean startNextMatchingActivity(IBinder callingActivity,
4499            Intent intent, Bundle bOptions) {
4500        // Refuse possible leaked file descriptors
4501        if (intent != null && intent.hasFileDescriptors() == true) {
4502            throw new IllegalArgumentException("File descriptors passed in Intent");
4503        }
4504        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4505
4506        synchronized (this) {
4507            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4508            if (r == null) {
4509                ActivityOptions.abort(options);
4510                return false;
4511            }
4512            if (r.app == null || r.app.thread == null) {
4513                // The caller is not running...  d'oh!
4514                ActivityOptions.abort(options);
4515                return false;
4516            }
4517            intent = new Intent(intent);
4518            // The caller is not allowed to change the data.
4519            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4520            // And we are resetting to find the next component...
4521            intent.setComponent(null);
4522
4523            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4524
4525            ActivityInfo aInfo = null;
4526            try {
4527                List<ResolveInfo> resolves =
4528                    AppGlobals.getPackageManager().queryIntentActivities(
4529                            intent, r.resolvedType,
4530                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4531                            UserHandle.getCallingUserId()).getList();
4532
4533                // Look for the original activity in the list...
4534                final int N = resolves != null ? resolves.size() : 0;
4535                for (int i=0; i<N; i++) {
4536                    ResolveInfo rInfo = resolves.get(i);
4537                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4538                            && rInfo.activityInfo.name.equals(r.info.name)) {
4539                        // We found the current one...  the next matching is
4540                        // after it.
4541                        i++;
4542                        if (i<N) {
4543                            aInfo = resolves.get(i).activityInfo;
4544                        }
4545                        if (debug) {
4546                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4547                                    + "/" + r.info.name);
4548                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4549                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4550                        }
4551                        break;
4552                    }
4553                }
4554            } catch (RemoteException e) {
4555            }
4556
4557            if (aInfo == null) {
4558                // Nobody who is next!
4559                ActivityOptions.abort(options);
4560                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4561                return false;
4562            }
4563
4564            intent.setComponent(new ComponentName(
4565                    aInfo.applicationInfo.packageName, aInfo.name));
4566            intent.setFlags(intent.getFlags()&~(
4567                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4568                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4569                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4570                    Intent.FLAG_ACTIVITY_NEW_TASK));
4571
4572            // Okay now we need to start the new activity, replacing the
4573            // currently running activity.  This is a little tricky because
4574            // we want to start the new one as if the current one is finished,
4575            // but not finish the current one first so that there is no flicker.
4576            // And thus...
4577            final boolean wasFinishing = r.finishing;
4578            r.finishing = true;
4579
4580            // Propagate reply information over to the new activity.
4581            final ActivityRecord resultTo = r.resultTo;
4582            final String resultWho = r.resultWho;
4583            final int requestCode = r.requestCode;
4584            r.resultTo = null;
4585            if (resultTo != null) {
4586                resultTo.removeResultsLocked(r, resultWho, requestCode);
4587            }
4588
4589            final long origId = Binder.clearCallingIdentity();
4590            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4591                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4592                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4593                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4594                    false, false, null, null, null);
4595            Binder.restoreCallingIdentity(origId);
4596
4597            r.finishing = wasFinishing;
4598            if (res != ActivityManager.START_SUCCESS) {
4599                return false;
4600            }
4601            return true;
4602        }
4603    }
4604
4605    @Override
4606    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4607        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4608            String msg = "Permission Denial: startActivityFromRecents called without " +
4609                    START_TASKS_FROM_RECENTS;
4610            Slog.w(TAG, msg);
4611            throw new SecurityException(msg);
4612        }
4613        final long origId = Binder.clearCallingIdentity();
4614        try {
4615            synchronized (this) {
4616                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4617            }
4618        } finally {
4619            Binder.restoreCallingIdentity(origId);
4620        }
4621    }
4622
4623    final int startActivityInPackage(int uid, String callingPackage,
4624            Intent intent, String resolvedType, IBinder resultTo,
4625            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4626            IActivityContainer container, TaskRecord inTask) {
4627
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4630
4631        // TODO: Switch to user app stacks here.
4632        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4633                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4634                null, null, null, bOptions, false, userId, container, inTask);
4635        return ret;
4636    }
4637
4638    @Override
4639    public final int startActivities(IApplicationThread caller, String callingPackage,
4640            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4641            int userId) {
4642        enforceNotIsolatedCaller("startActivities");
4643        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4644                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4645        // TODO: Switch to user app stacks here.
4646        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4647                resolvedTypes, resultTo, bOptions, userId);
4648        return ret;
4649    }
4650
4651    final int startActivitiesInPackage(int uid, String callingPackage,
4652            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4653            Bundle bOptions, int userId) {
4654
4655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4656                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4657        // TODO: Switch to user app stacks here.
4658        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4659                resultTo, bOptions, userId);
4660        return ret;
4661    }
4662
4663    @Override
4664    public void reportActivityFullyDrawn(IBinder token) {
4665        synchronized (this) {
4666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4667            if (r == null) {
4668                return;
4669            }
4670            r.reportFullyDrawnLocked();
4671        }
4672    }
4673
4674    @Override
4675    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4676        synchronized (this) {
4677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4678            if (r == null) {
4679                return;
4680            }
4681            TaskRecord task = r.task;
4682            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4683                // Fixed screen orientation isn't supported when activities aren't in full screen
4684                // mode.
4685                return;
4686            }
4687            final long origId = Binder.clearCallingIdentity();
4688            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4689            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4690                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4691            if (config != null) {
4692                r.frozenBeforeDestroy = true;
4693                if (!updateConfigurationLocked(config, r, false)) {
4694                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4695                }
4696            }
4697            Binder.restoreCallingIdentity(origId);
4698        }
4699    }
4700
4701    @Override
4702    public int getRequestedOrientation(IBinder token) {
4703        synchronized (this) {
4704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4705            if (r == null) {
4706                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4707            }
4708            return mWindowManager.getAppOrientation(r.appToken);
4709        }
4710    }
4711
4712    /**
4713     * This is the internal entry point for handling Activity.finish().
4714     *
4715     * @param token The Binder token referencing the Activity we want to finish.
4716     * @param resultCode Result code, if any, from this Activity.
4717     * @param resultData Result data (Intent), if any, from this Activity.
4718     * @param finishTask Whether to finish the task associated with this Activity.
4719     *
4720     * @return Returns true if the activity successfully finished, or false if it is still running.
4721     */
4722    @Override
4723    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4724            int finishTask) {
4725        // Refuse possible leaked file descriptors
4726        if (resultData != null && resultData.hasFileDescriptors() == true) {
4727            throw new IllegalArgumentException("File descriptors passed in Intent");
4728        }
4729
4730        synchronized(this) {
4731            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4732            if (r == null) {
4733                return true;
4734            }
4735            // Keep track of the root activity of the task before we finish it
4736            TaskRecord tr = r.task;
4737            ActivityRecord rootR = tr.getRootActivity();
4738            if (rootR == null) {
4739                Slog.w(TAG, "Finishing task with all activities already finished");
4740            }
4741            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4742            // finish.
4743            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4744                    mStackSupervisor.isLastLockedTask(tr)) {
4745                Slog.i(TAG, "Not finishing task in lock task mode");
4746                mStackSupervisor.showLockTaskToast();
4747                return false;
4748            }
4749            if (mController != null) {
4750                // Find the first activity that is not finishing.
4751                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4752                if (next != null) {
4753                    // ask watcher if this is allowed
4754                    boolean resumeOK = true;
4755                    try {
4756                        resumeOK = mController.activityResuming(next.packageName);
4757                    } catch (RemoteException e) {
4758                        mController = null;
4759                        Watchdog.getInstance().setActivityController(null);
4760                    }
4761
4762                    if (!resumeOK) {
4763                        Slog.i(TAG, "Not finishing activity because controller resumed");
4764                        return false;
4765                    }
4766                }
4767            }
4768            final long origId = Binder.clearCallingIdentity();
4769            try {
4770                boolean res;
4771                final boolean finishWithRootActivity =
4772                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4773                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4774                        || (finishWithRootActivity && r == rootR)) {
4775                    // If requested, remove the task that is associated to this activity only if it
4776                    // was the root activity in the task. The result code and data is ignored
4777                    // because we don't support returning them across task boundaries. Also, to
4778                    // keep backwards compatibility we remove the task from recents when finishing
4779                    // task with root activity.
4780                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4781                    if (!res) {
4782                        Slog.i(TAG, "Removing task failed to finish activity");
4783                    }
4784                } else {
4785                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4786                            resultData, "app-request", true);
4787                    if (!res) {
4788                        Slog.i(TAG, "Failed to finish by app-request");
4789                    }
4790                }
4791                return res;
4792            } finally {
4793                Binder.restoreCallingIdentity(origId);
4794            }
4795        }
4796    }
4797
4798    @Override
4799    public final void finishHeavyWeightApp() {
4800        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4801                != PackageManager.PERMISSION_GRANTED) {
4802            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4803                    + Binder.getCallingPid()
4804                    + ", uid=" + Binder.getCallingUid()
4805                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4806            Slog.w(TAG, msg);
4807            throw new SecurityException(msg);
4808        }
4809
4810        synchronized(this) {
4811            if (mHeavyWeightProcess == null) {
4812                return;
4813            }
4814
4815            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4816            for (int i = 0; i < activities.size(); i++) {
4817                ActivityRecord r = activities.get(i);
4818                if (!r.finishing && r.isInStackLocked()) {
4819                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4820                            null, "finish-heavy", true);
4821                }
4822            }
4823
4824            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4825                    mHeavyWeightProcess.userId, 0));
4826            mHeavyWeightProcess = null;
4827        }
4828    }
4829
4830    @Override
4831    public void crashApplication(int uid, int initialPid, String packageName,
4832            String message) {
4833        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4834                != PackageManager.PERMISSION_GRANTED) {
4835            String msg = "Permission Denial: crashApplication() from pid="
4836                    + Binder.getCallingPid()
4837                    + ", uid=" + Binder.getCallingUid()
4838                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4839            Slog.w(TAG, msg);
4840            throw new SecurityException(msg);
4841        }
4842
4843        synchronized(this) {
4844            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4845        }
4846    }
4847
4848    @Override
4849    public final void finishSubActivity(IBinder token, String resultWho,
4850            int requestCode) {
4851        synchronized(this) {
4852            final long origId = Binder.clearCallingIdentity();
4853            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4854            if (r != null) {
4855                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4856            }
4857            Binder.restoreCallingIdentity(origId);
4858        }
4859    }
4860
4861    @Override
4862    public boolean finishActivityAffinity(IBinder token) {
4863        synchronized(this) {
4864            final long origId = Binder.clearCallingIdentity();
4865            try {
4866                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4867                if (r == null) {
4868                    return false;
4869                }
4870
4871                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4872                // can finish.
4873                final TaskRecord task = r.task;
4874                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4875                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4876                    mStackSupervisor.showLockTaskToast();
4877                    return false;
4878                }
4879                return task.stack.finishActivityAffinityLocked(r);
4880            } finally {
4881                Binder.restoreCallingIdentity(origId);
4882            }
4883        }
4884    }
4885
4886    @Override
4887    public void finishVoiceTask(IVoiceInteractionSession session) {
4888        synchronized (this) {
4889            final long origId = Binder.clearCallingIdentity();
4890            try {
4891                // TODO: VI Consider treating local voice interactions and voice tasks
4892                // differently here
4893                mStackSupervisor.finishVoiceTask(session);
4894            } finally {
4895                Binder.restoreCallingIdentity(origId);
4896            }
4897        }
4898
4899    }
4900
4901    @Override
4902    public boolean releaseActivityInstance(IBinder token) {
4903        synchronized(this) {
4904            final long origId = Binder.clearCallingIdentity();
4905            try {
4906                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4907                if (r == null) {
4908                    return false;
4909                }
4910                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4911            } finally {
4912                Binder.restoreCallingIdentity(origId);
4913            }
4914        }
4915    }
4916
4917    @Override
4918    public void releaseSomeActivities(IApplicationThread appInt) {
4919        synchronized(this) {
4920            final long origId = Binder.clearCallingIdentity();
4921            try {
4922                ProcessRecord app = getRecordForAppLocked(appInt);
4923                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4924            } finally {
4925                Binder.restoreCallingIdentity(origId);
4926            }
4927        }
4928    }
4929
4930    @Override
4931    public boolean willActivityBeVisible(IBinder token) {
4932        synchronized(this) {
4933            ActivityStack stack = ActivityRecord.getStackLocked(token);
4934            if (stack != null) {
4935                return stack.willActivityBeVisibleLocked(token);
4936            }
4937            return false;
4938        }
4939    }
4940
4941    @Override
4942    public void overridePendingTransition(IBinder token, String packageName,
4943            int enterAnim, int exitAnim) {
4944        synchronized(this) {
4945            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4946            if (self == null) {
4947                return;
4948            }
4949
4950            final long origId = Binder.clearCallingIdentity();
4951
4952            if (self.state == ActivityState.RESUMED
4953                    || self.state == ActivityState.PAUSING) {
4954                mWindowManager.overridePendingAppTransition(packageName,
4955                        enterAnim, exitAnim, null);
4956            }
4957
4958            Binder.restoreCallingIdentity(origId);
4959        }
4960    }
4961
4962    /**
4963     * Main function for removing an existing process from the activity manager
4964     * as a result of that process going away.  Clears out all connections
4965     * to the process.
4966     */
4967    private final void handleAppDiedLocked(ProcessRecord app,
4968            boolean restarting, boolean allowRestart) {
4969        int pid = app.pid;
4970        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4971        if (!kept && !restarting) {
4972            removeLruProcessLocked(app);
4973            if (pid > 0) {
4974                ProcessList.remove(pid);
4975            }
4976        }
4977
4978        if (mProfileProc == app) {
4979            clearProfilerLocked();
4980        }
4981
4982        // Remove this application's activities from active lists.
4983        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4984
4985        app.activities.clear();
4986
4987        if (app.instrumentationClass != null) {
4988            Slog.w(TAG, "Crash of app " + app.processName
4989                  + " running instrumentation " + app.instrumentationClass);
4990            Bundle info = new Bundle();
4991            info.putString("shortMsg", "Process crashed.");
4992            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4993        }
4994
4995        if (!restarting && hasVisibleActivities
4996                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4997            // If there was nothing to resume, and we are not already restarting this process, but
4998            // there is a visible activity that is hosted by the process...  then make sure all
4999            // visible activities are running, taking care of restarting this process.
5000            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5001        }
5002    }
5003
5004    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5005        IBinder threadBinder = thread.asBinder();
5006        // Find the application record.
5007        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5008            ProcessRecord rec = mLruProcesses.get(i);
5009            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5010                return i;
5011            }
5012        }
5013        return -1;
5014    }
5015
5016    final ProcessRecord getRecordForAppLocked(
5017            IApplicationThread thread) {
5018        if (thread == null) {
5019            return null;
5020        }
5021
5022        int appIndex = getLRURecordIndexForAppLocked(thread);
5023        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5024    }
5025
5026    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5027        // If there are no longer any background processes running,
5028        // and the app that died was not running instrumentation,
5029        // then tell everyone we are now low on memory.
5030        boolean haveBg = false;
5031        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5032            ProcessRecord rec = mLruProcesses.get(i);
5033            if (rec.thread != null
5034                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5035                haveBg = true;
5036                break;
5037            }
5038        }
5039
5040        if (!haveBg) {
5041            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5042            if (doReport) {
5043                long now = SystemClock.uptimeMillis();
5044                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5045                    doReport = false;
5046                } else {
5047                    mLastMemUsageReportTime = now;
5048                }
5049            }
5050            final ArrayList<ProcessMemInfo> memInfos
5051                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5052            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5053            long now = SystemClock.uptimeMillis();
5054            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5055                ProcessRecord rec = mLruProcesses.get(i);
5056                if (rec == dyingProc || rec.thread == null) {
5057                    continue;
5058                }
5059                if (doReport) {
5060                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5061                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5062                }
5063                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5064                    // The low memory report is overriding any current
5065                    // state for a GC request.  Make sure to do
5066                    // heavy/important/visible/foreground processes first.
5067                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5068                        rec.lastRequestedGc = 0;
5069                    } else {
5070                        rec.lastRequestedGc = rec.lastLowMemory;
5071                    }
5072                    rec.reportLowMemory = true;
5073                    rec.lastLowMemory = now;
5074                    mProcessesToGc.remove(rec);
5075                    addProcessToGcListLocked(rec);
5076                }
5077            }
5078            if (doReport) {
5079                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5080                mHandler.sendMessage(msg);
5081            }
5082            scheduleAppGcsLocked();
5083        }
5084    }
5085
5086    final void appDiedLocked(ProcessRecord app) {
5087       appDiedLocked(app, app.pid, app.thread, false);
5088    }
5089
5090    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5091            boolean fromBinderDied) {
5092        // First check if this ProcessRecord is actually active for the pid.
5093        synchronized (mPidsSelfLocked) {
5094            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5095            if (curProc != app) {
5096                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5097                return;
5098            }
5099        }
5100
5101        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5102        synchronized (stats) {
5103            stats.noteProcessDiedLocked(app.info.uid, pid);
5104        }
5105
5106        if (!app.killed) {
5107            if (!fromBinderDied) {
5108                Process.killProcessQuiet(pid);
5109            }
5110            killProcessGroup(app.uid, pid);
5111            app.killed = true;
5112        }
5113
5114        // Clean up already done if the process has been re-started.
5115        if (app.pid == pid && app.thread != null &&
5116                app.thread.asBinder() == thread.asBinder()) {
5117            boolean doLowMem = app.instrumentationClass == null;
5118            boolean doOomAdj = doLowMem;
5119            if (!app.killedByAm) {
5120                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5121                        + ") has died");
5122                mAllowLowerMemLevel = true;
5123            } else {
5124                // Note that we always want to do oom adj to update our state with the
5125                // new number of procs.
5126                mAllowLowerMemLevel = false;
5127                doLowMem = false;
5128            }
5129            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5130            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5131                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5132            handleAppDiedLocked(app, false, true);
5133
5134            if (doOomAdj) {
5135                updateOomAdjLocked();
5136            }
5137            if (doLowMem) {
5138                doLowMemReportIfNeededLocked(app);
5139            }
5140        } else if (app.pid != pid) {
5141            // A new process has already been started.
5142            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5143                    + ") has died and restarted (pid " + app.pid + ").");
5144            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5145        } else if (DEBUG_PROCESSES) {
5146            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5147                    + thread.asBinder());
5148        }
5149    }
5150
5151    /**
5152     * If a stack trace dump file is configured, dump process stack traces.
5153     * @param clearTraces causes the dump file to be erased prior to the new
5154     *    traces being written, if true; when false, the new traces will be
5155     *    appended to any existing file content.
5156     * @param firstPids of dalvik VM processes to dump stack traces for first
5157     * @param lastPids of dalvik VM processes to dump stack traces for last
5158     * @param nativeProcs optional list of native process names to dump stack crawls
5159     * @return file containing stack traces, or null if no dump file is configured
5160     */
5161    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5162            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5163        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5164        if (tracesPath == null || tracesPath.length() == 0) {
5165            return null;
5166        }
5167
5168        File tracesFile = new File(tracesPath);
5169        try {
5170            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5171            tracesFile.createNewFile();
5172            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5173        } catch (IOException e) {
5174            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5175            return null;
5176        }
5177
5178        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5179        return tracesFile;
5180    }
5181
5182    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5183            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5184        // Use a FileObserver to detect when traces finish writing.
5185        // The order of traces is considered important to maintain for legibility.
5186        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5187            @Override
5188            public synchronized void onEvent(int event, String path) { notify(); }
5189        };
5190
5191        try {
5192            observer.startWatching();
5193
5194            // First collect all of the stacks of the most important pids.
5195            if (firstPids != null) {
5196                try {
5197                    int num = firstPids.size();
5198                    for (int i = 0; i < num; i++) {
5199                        synchronized (observer) {
5200                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5201                                    + firstPids.get(i));
5202                            final long sime = SystemClock.elapsedRealtime();
5203                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5204                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5205                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5206                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5207                        }
5208                    }
5209                } catch (InterruptedException e) {
5210                    Slog.wtf(TAG, e);
5211                }
5212            }
5213
5214            // Next collect the stacks of the native pids
5215            if (nativeProcs != null) {
5216                int[] pids = Process.getPidsForCommands(nativeProcs);
5217                if (pids != null) {
5218                    for (int pid : pids) {
5219                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5220                        final long sime = SystemClock.elapsedRealtime();
5221                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5222                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5223                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5224                    }
5225                }
5226            }
5227
5228            // Lastly, measure CPU usage.
5229            if (processCpuTracker != null) {
5230                processCpuTracker.init();
5231                System.gc();
5232                processCpuTracker.update();
5233                try {
5234                    synchronized (processCpuTracker) {
5235                        processCpuTracker.wait(500); // measure over 1/2 second.
5236                    }
5237                } catch (InterruptedException e) {
5238                }
5239                processCpuTracker.update();
5240
5241                // We'll take the stack crawls of just the top apps using CPU.
5242                final int N = processCpuTracker.countWorkingStats();
5243                int numProcs = 0;
5244                for (int i=0; i<N && numProcs<5; i++) {
5245                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5246                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5247                        numProcs++;
5248                        try {
5249                            synchronized (observer) {
5250                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5251                                        + stats.pid);
5252                                final long stime = SystemClock.elapsedRealtime();
5253                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5254                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5255                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5256                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5257                            }
5258                        } catch (InterruptedException e) {
5259                            Slog.wtf(TAG, e);
5260                        }
5261                    } else if (DEBUG_ANR) {
5262                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5263                                + stats.pid);
5264                    }
5265                }
5266            }
5267        } finally {
5268            observer.stopWatching();
5269        }
5270    }
5271
5272    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5273        if (true || IS_USER_BUILD) {
5274            return;
5275        }
5276        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5277        if (tracesPath == null || tracesPath.length() == 0) {
5278            return;
5279        }
5280
5281        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5282        StrictMode.allowThreadDiskWrites();
5283        try {
5284            final File tracesFile = new File(tracesPath);
5285            final File tracesDir = tracesFile.getParentFile();
5286            final File tracesTmp = new File(tracesDir, "__tmp__");
5287            try {
5288                if (tracesFile.exists()) {
5289                    tracesTmp.delete();
5290                    tracesFile.renameTo(tracesTmp);
5291                }
5292                StringBuilder sb = new StringBuilder();
5293                Time tobj = new Time();
5294                tobj.set(System.currentTimeMillis());
5295                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5296                sb.append(": ");
5297                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5298                sb.append(" since ");
5299                sb.append(msg);
5300                FileOutputStream fos = new FileOutputStream(tracesFile);
5301                fos.write(sb.toString().getBytes());
5302                if (app == null) {
5303                    fos.write("\n*** No application process!".getBytes());
5304                }
5305                fos.close();
5306                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5307            } catch (IOException e) {
5308                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5309                return;
5310            }
5311
5312            if (app != null) {
5313                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5314                firstPids.add(app.pid);
5315                dumpStackTraces(tracesPath, firstPids, null, null, null);
5316            }
5317
5318            File lastTracesFile = null;
5319            File curTracesFile = null;
5320            for (int i=9; i>=0; i--) {
5321                String name = String.format(Locale.US, "slow%02d.txt", i);
5322                curTracesFile = new File(tracesDir, name);
5323                if (curTracesFile.exists()) {
5324                    if (lastTracesFile != null) {
5325                        curTracesFile.renameTo(lastTracesFile);
5326                    } else {
5327                        curTracesFile.delete();
5328                    }
5329                }
5330                lastTracesFile = curTracesFile;
5331            }
5332            tracesFile.renameTo(curTracesFile);
5333            if (tracesTmp.exists()) {
5334                tracesTmp.renameTo(tracesFile);
5335            }
5336        } finally {
5337            StrictMode.setThreadPolicy(oldPolicy);
5338        }
5339    }
5340
5341    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5342        if (!mLaunchWarningShown) {
5343            mLaunchWarningShown = true;
5344            mUiHandler.post(new Runnable() {
5345                @Override
5346                public void run() {
5347                    synchronized (ActivityManagerService.this) {
5348                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5349                        d.show();
5350                        mUiHandler.postDelayed(new Runnable() {
5351                            @Override
5352                            public void run() {
5353                                synchronized (ActivityManagerService.this) {
5354                                    d.dismiss();
5355                                    mLaunchWarningShown = false;
5356                                }
5357                            }
5358                        }, 4000);
5359                    }
5360                }
5361            });
5362        }
5363    }
5364
5365    @Override
5366    public boolean clearApplicationUserData(final String packageName,
5367            final IPackageDataObserver observer, int userId) {
5368        enforceNotIsolatedCaller("clearApplicationUserData");
5369        int uid = Binder.getCallingUid();
5370        int pid = Binder.getCallingPid();
5371        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5372                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5373
5374        final DevicePolicyManagerInternal dpmi = LocalServices
5375                .getService(DevicePolicyManagerInternal.class);
5376        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5377            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5378        }
5379
5380        long callingId = Binder.clearCallingIdentity();
5381        try {
5382            IPackageManager pm = AppGlobals.getPackageManager();
5383            int pkgUid = -1;
5384            synchronized(this) {
5385                try {
5386                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5387                } catch (RemoteException e) {
5388                }
5389                if (pkgUid == -1) {
5390                    Slog.w(TAG, "Invalid packageName: " + packageName);
5391                    if (observer != null) {
5392                        try {
5393                            observer.onRemoveCompleted(packageName, false);
5394                        } catch (RemoteException e) {
5395                            Slog.i(TAG, "Observer no longer exists.");
5396                        }
5397                    }
5398                    return false;
5399                }
5400                if (uid == pkgUid || checkComponentPermission(
5401                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5402                        pid, uid, -1, true)
5403                        == PackageManager.PERMISSION_GRANTED) {
5404                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5405                } else {
5406                    throw new SecurityException("PID " + pid + " does not have permission "
5407                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5408                                    + " of package " + packageName);
5409                }
5410
5411                // Remove all tasks match the cleared application package and user
5412                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5413                    final TaskRecord tr = mRecentTasks.get(i);
5414                    final String taskPackageName =
5415                            tr.getBaseIntent().getComponent().getPackageName();
5416                    if (tr.userId != userId) continue;
5417                    if (!taskPackageName.equals(packageName)) continue;
5418                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5419                }
5420            }
5421
5422            try {
5423                // Clear application user data
5424                pm.clearApplicationUserData(packageName, observer, userId);
5425
5426                synchronized(this) {
5427                    // Remove all permissions granted from/to this package
5428                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5429                }
5430
5431                // Remove all zen rules created by this package; revoke it's zen access.
5432                INotificationManager inm = NotificationManager.getService();
5433                inm.removeAutomaticZenRules(packageName);
5434                inm.setNotificationPolicyAccessGranted(packageName, false);
5435
5436                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5437                        Uri.fromParts("package", packageName, null));
5438                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5439                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5440                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5441                        null, null, 0, null, null, null, null, false, false, userId);
5442            } catch (RemoteException e) {
5443            }
5444        } finally {
5445            Binder.restoreCallingIdentity(callingId);
5446        }
5447        return true;
5448    }
5449
5450    @Override
5451    public void killBackgroundProcesses(final String packageName, int userId) {
5452        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5453                != PackageManager.PERMISSION_GRANTED &&
5454                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5455                        != PackageManager.PERMISSION_GRANTED) {
5456            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5457                    + Binder.getCallingPid()
5458                    + ", uid=" + Binder.getCallingUid()
5459                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5460            Slog.w(TAG, msg);
5461            throw new SecurityException(msg);
5462        }
5463
5464        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5465                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5466        long callingId = Binder.clearCallingIdentity();
5467        try {
5468            IPackageManager pm = AppGlobals.getPackageManager();
5469            synchronized(this) {
5470                int appId = -1;
5471                try {
5472                    appId = UserHandle.getAppId(
5473                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5474                } catch (RemoteException e) {
5475                }
5476                if (appId == -1) {
5477                    Slog.w(TAG, "Invalid packageName: " + packageName);
5478                    return;
5479                }
5480                killPackageProcessesLocked(packageName, appId, userId,
5481                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5482            }
5483        } finally {
5484            Binder.restoreCallingIdentity(callingId);
5485        }
5486    }
5487
5488    @Override
5489    public void killAllBackgroundProcesses() {
5490        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5491                != PackageManager.PERMISSION_GRANTED) {
5492            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5493                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5494                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5495            Slog.w(TAG, msg);
5496            throw new SecurityException(msg);
5497        }
5498
5499        final long callingId = Binder.clearCallingIdentity();
5500        try {
5501            synchronized (this) {
5502                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5503                final int NP = mProcessNames.getMap().size();
5504                for (int ip = 0; ip < NP; ip++) {
5505                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5506                    final int NA = apps.size();
5507                    for (int ia = 0; ia < NA; ia++) {
5508                        final ProcessRecord app = apps.valueAt(ia);
5509                        if (app.persistent) {
5510                            // We don't kill persistent processes.
5511                            continue;
5512                        }
5513                        if (app.removed) {
5514                            procs.add(app);
5515                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5516                            app.removed = true;
5517                            procs.add(app);
5518                        }
5519                    }
5520                }
5521
5522                final int N = procs.size();
5523                for (int i = 0; i < N; i++) {
5524                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5525                }
5526
5527                mAllowLowerMemLevel = true;
5528
5529                updateOomAdjLocked();
5530                doLowMemReportIfNeededLocked(null);
5531            }
5532        } finally {
5533            Binder.restoreCallingIdentity(callingId);
5534        }
5535    }
5536
5537    /**
5538     * Kills all background processes, except those matching any of the
5539     * specified properties.
5540     *
5541     * @param minTargetSdk the target SDK version at or above which to preserve
5542     *                     processes, or {@code -1} to ignore the target SDK
5543     * @param maxProcState the process state at or below which to preserve
5544     *                     processes, or {@code -1} to ignore the process state
5545     */
5546    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5547        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5548                != PackageManager.PERMISSION_GRANTED) {
5549            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5550                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5551                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5552            Slog.w(TAG, msg);
5553            throw new SecurityException(msg);
5554        }
5555
5556        final long callingId = Binder.clearCallingIdentity();
5557        try {
5558            synchronized (this) {
5559                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5560                final int NP = mProcessNames.getMap().size();
5561                for (int ip = 0; ip < NP; ip++) {
5562                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5563                    final int NA = apps.size();
5564                    for (int ia = 0; ia < NA; ia++) {
5565                        final ProcessRecord app = apps.valueAt(ia);
5566                        if (app.removed) {
5567                            procs.add(app);
5568                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5569                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5570                            app.removed = true;
5571                            procs.add(app);
5572                        }
5573                    }
5574                }
5575
5576                final int N = procs.size();
5577                for (int i = 0; i < N; i++) {
5578                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5579                }
5580            }
5581        } finally {
5582            Binder.restoreCallingIdentity(callingId);
5583        }
5584    }
5585
5586    @Override
5587    public void forceStopPackage(final String packageName, int userId) {
5588        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5589                != PackageManager.PERMISSION_GRANTED) {
5590            String msg = "Permission Denial: forceStopPackage() from pid="
5591                    + Binder.getCallingPid()
5592                    + ", uid=" + Binder.getCallingUid()
5593                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5594            Slog.w(TAG, msg);
5595            throw new SecurityException(msg);
5596        }
5597        final int callingPid = Binder.getCallingPid();
5598        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5599                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5600        long callingId = Binder.clearCallingIdentity();
5601        try {
5602            IPackageManager pm = AppGlobals.getPackageManager();
5603            synchronized(this) {
5604                int[] users = userId == UserHandle.USER_ALL
5605                        ? mUserController.getUsers() : new int[] { userId };
5606                for (int user : users) {
5607                    int pkgUid = -1;
5608                    try {
5609                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5610                                user);
5611                    } catch (RemoteException e) {
5612                    }
5613                    if (pkgUid == -1) {
5614                        Slog.w(TAG, "Invalid packageName: " + packageName);
5615                        continue;
5616                    }
5617                    try {
5618                        pm.setPackageStoppedState(packageName, true, user);
5619                    } catch (RemoteException e) {
5620                    } catch (IllegalArgumentException e) {
5621                        Slog.w(TAG, "Failed trying to unstop package "
5622                                + packageName + ": " + e);
5623                    }
5624                    if (mUserController.isUserRunningLocked(user, 0)) {
5625                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5626                    }
5627                }
5628            }
5629        } finally {
5630            Binder.restoreCallingIdentity(callingId);
5631        }
5632    }
5633
5634    @Override
5635    public void addPackageDependency(String packageName) {
5636        synchronized (this) {
5637            int callingPid = Binder.getCallingPid();
5638            if (callingPid == Process.myPid()) {
5639                //  Yeah, um, no.
5640                return;
5641            }
5642            ProcessRecord proc;
5643            synchronized (mPidsSelfLocked) {
5644                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5645            }
5646            if (proc != null) {
5647                if (proc.pkgDeps == null) {
5648                    proc.pkgDeps = new ArraySet<String>(1);
5649                }
5650                proc.pkgDeps.add(packageName);
5651            }
5652        }
5653    }
5654
5655    /*
5656     * The pkg name and app id have to be specified.
5657     */
5658    @Override
5659    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5660        if (pkg == null) {
5661            return;
5662        }
5663        // Make sure the uid is valid.
5664        if (appid < 0) {
5665            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5666            return;
5667        }
5668        int callerUid = Binder.getCallingUid();
5669        // Only the system server can kill an application
5670        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5671            // Post an aysnc message to kill the application
5672            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5673            msg.arg1 = appid;
5674            msg.arg2 = 0;
5675            Bundle bundle = new Bundle();
5676            bundle.putString("pkg", pkg);
5677            bundle.putString("reason", reason);
5678            msg.obj = bundle;
5679            mHandler.sendMessage(msg);
5680        } else {
5681            throw new SecurityException(callerUid + " cannot kill pkg: " +
5682                    pkg);
5683        }
5684    }
5685
5686    @Override
5687    public void closeSystemDialogs(String reason) {
5688        enforceNotIsolatedCaller("closeSystemDialogs");
5689
5690        final int pid = Binder.getCallingPid();
5691        final int uid = Binder.getCallingUid();
5692        final long origId = Binder.clearCallingIdentity();
5693        try {
5694            synchronized (this) {
5695                // Only allow this from foreground processes, so that background
5696                // applications can't abuse it to prevent system UI from being shown.
5697                if (uid >= Process.FIRST_APPLICATION_UID) {
5698                    ProcessRecord proc;
5699                    synchronized (mPidsSelfLocked) {
5700                        proc = mPidsSelfLocked.get(pid);
5701                    }
5702                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5703                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5704                                + " from background process " + proc);
5705                        return;
5706                    }
5707                }
5708                closeSystemDialogsLocked(reason);
5709            }
5710        } finally {
5711            Binder.restoreCallingIdentity(origId);
5712        }
5713    }
5714
5715    void closeSystemDialogsLocked(String reason) {
5716        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5717        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5718                | Intent.FLAG_RECEIVER_FOREGROUND);
5719        if (reason != null) {
5720            intent.putExtra("reason", reason);
5721        }
5722        mWindowManager.closeSystemDialogs(reason);
5723
5724        mStackSupervisor.closeSystemDialogsLocked();
5725
5726        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5727                AppOpsManager.OP_NONE, null, false, false,
5728                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5729    }
5730
5731    @Override
5732    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5733        enforceNotIsolatedCaller("getProcessMemoryInfo");
5734        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5735        for (int i=pids.length-1; i>=0; i--) {
5736            ProcessRecord proc;
5737            int oomAdj;
5738            synchronized (this) {
5739                synchronized (mPidsSelfLocked) {
5740                    proc = mPidsSelfLocked.get(pids[i]);
5741                    oomAdj = proc != null ? proc.setAdj : 0;
5742                }
5743            }
5744            infos[i] = new Debug.MemoryInfo();
5745            Debug.getMemoryInfo(pids[i], infos[i]);
5746            if (proc != null) {
5747                synchronized (this) {
5748                    if (proc.thread != null && proc.setAdj == oomAdj) {
5749                        // Record this for posterity if the process has been stable.
5750                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5751                                infos[i].getTotalUss(), false, proc.pkgList);
5752                    }
5753                }
5754            }
5755        }
5756        return infos;
5757    }
5758
5759    @Override
5760    public long[] getProcessPss(int[] pids) {
5761        enforceNotIsolatedCaller("getProcessPss");
5762        long[] pss = new long[pids.length];
5763        for (int i=pids.length-1; i>=0; i--) {
5764            ProcessRecord proc;
5765            int oomAdj;
5766            synchronized (this) {
5767                synchronized (mPidsSelfLocked) {
5768                    proc = mPidsSelfLocked.get(pids[i]);
5769                    oomAdj = proc != null ? proc.setAdj : 0;
5770                }
5771            }
5772            long[] tmpUss = new long[1];
5773            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5774            if (proc != null) {
5775                synchronized (this) {
5776                    if (proc.thread != null && proc.setAdj == oomAdj) {
5777                        // Record this for posterity if the process has been stable.
5778                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5779                    }
5780                }
5781            }
5782        }
5783        return pss;
5784    }
5785
5786    @Override
5787    public void killApplicationProcess(String processName, int uid) {
5788        if (processName == null) {
5789            return;
5790        }
5791
5792        int callerUid = Binder.getCallingUid();
5793        // Only the system server can kill an application
5794        if (callerUid == Process.SYSTEM_UID) {
5795            synchronized (this) {
5796                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5797                if (app != null && app.thread != null) {
5798                    try {
5799                        app.thread.scheduleSuicide();
5800                    } catch (RemoteException e) {
5801                        // If the other end already died, then our work here is done.
5802                    }
5803                } else {
5804                    Slog.w(TAG, "Process/uid not found attempting kill of "
5805                            + processName + " / " + uid);
5806                }
5807            }
5808        } else {
5809            throw new SecurityException(callerUid + " cannot kill app process: " +
5810                    processName);
5811        }
5812    }
5813
5814    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5815        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5816                false, true, false, false, UserHandle.getUserId(uid), reason);
5817        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5818                Uri.fromParts("package", packageName, null));
5819        if (!mProcessesReady) {
5820            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5821                    | Intent.FLAG_RECEIVER_FOREGROUND);
5822        }
5823        intent.putExtra(Intent.EXTRA_UID, uid);
5824        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5825        broadcastIntentLocked(null, null, intent,
5826                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5827                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5828    }
5829
5830
5831    private final boolean killPackageProcessesLocked(String packageName, int appId,
5832            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5833            boolean doit, boolean evenPersistent, String reason) {
5834        ArrayList<ProcessRecord> procs = new ArrayList<>();
5835
5836        // Remove all processes this package may have touched: all with the
5837        // same UID (except for the system or root user), and all whose name
5838        // matches the package name.
5839        final int NP = mProcessNames.getMap().size();
5840        for (int ip=0; ip<NP; ip++) {
5841            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5842            final int NA = apps.size();
5843            for (int ia=0; ia<NA; ia++) {
5844                ProcessRecord app = apps.valueAt(ia);
5845                if (app.persistent && !evenPersistent) {
5846                    // we don't kill persistent processes
5847                    continue;
5848                }
5849                if (app.removed) {
5850                    if (doit) {
5851                        procs.add(app);
5852                    }
5853                    continue;
5854                }
5855
5856                // Skip process if it doesn't meet our oom adj requirement.
5857                if (app.setAdj < minOomAdj) {
5858                    continue;
5859                }
5860
5861                // If no package is specified, we call all processes under the
5862                // give user id.
5863                if (packageName == null) {
5864                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5865                        continue;
5866                    }
5867                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5868                        continue;
5869                    }
5870                // Package has been specified, we want to hit all processes
5871                // that match it.  We need to qualify this by the processes
5872                // that are running under the specified app and user ID.
5873                } else {
5874                    final boolean isDep = app.pkgDeps != null
5875                            && app.pkgDeps.contains(packageName);
5876                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5877                        continue;
5878                    }
5879                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5880                        continue;
5881                    }
5882                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5883                        continue;
5884                    }
5885                }
5886
5887                // Process has passed all conditions, kill it!
5888                if (!doit) {
5889                    return true;
5890                }
5891                app.removed = true;
5892                procs.add(app);
5893            }
5894        }
5895
5896        int N = procs.size();
5897        for (int i=0; i<N; i++) {
5898            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5899        }
5900        updateOomAdjLocked();
5901        return N > 0;
5902    }
5903
5904    private void cleanupDisabledPackageComponentsLocked(
5905            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5906
5907        Set<String> disabledClasses = null;
5908        boolean packageDisabled = false;
5909        IPackageManager pm = AppGlobals.getPackageManager();
5910
5911        if (changedClasses == null) {
5912            // Nothing changed...
5913            return;
5914        }
5915
5916        // Determine enable/disable state of the package and its components.
5917        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5918        for (int i = changedClasses.length - 1; i >= 0; i--) {
5919            final String changedClass = changedClasses[i];
5920
5921            if (changedClass.equals(packageName)) {
5922                try {
5923                    // Entire package setting changed
5924                    enabled = pm.getApplicationEnabledSetting(packageName,
5925                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5926                } catch (Exception e) {
5927                    // No such package/component; probably racing with uninstall.  In any
5928                    // event it means we have nothing further to do here.
5929                    return;
5930                }
5931                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5932                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5933                if (packageDisabled) {
5934                    // Entire package is disabled.
5935                    // No need to continue to check component states.
5936                    disabledClasses = null;
5937                    break;
5938                }
5939            } else {
5940                try {
5941                    enabled = pm.getComponentEnabledSetting(
5942                            new ComponentName(packageName, changedClass),
5943                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5944                } catch (Exception e) {
5945                    // As above, probably racing with uninstall.
5946                    return;
5947                }
5948                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5949                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5950                    if (disabledClasses == null) {
5951                        disabledClasses = new ArraySet<>(changedClasses.length);
5952                    }
5953                    disabledClasses.add(changedClass);
5954                }
5955            }
5956        }
5957
5958        if (!packageDisabled && disabledClasses == null) {
5959            // Nothing to do here...
5960            return;
5961        }
5962
5963        // Clean-up disabled activities.
5964        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5965                packageName, disabledClasses, true, false, userId) && mBooted) {
5966            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5967            mStackSupervisor.scheduleIdleLocked();
5968        }
5969
5970        // Clean-up disabled tasks
5971        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5972
5973        // Clean-up disabled services.
5974        mServices.bringDownDisabledPackageServicesLocked(
5975                packageName, disabledClasses, userId, false, killProcess, true);
5976
5977        // Clean-up disabled providers.
5978        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5979        mProviderMap.collectPackageProvidersLocked(
5980                packageName, disabledClasses, true, false, userId, providers);
5981        for (int i = providers.size() - 1; i >= 0; i--) {
5982            removeDyingProviderLocked(null, providers.get(i), true);
5983        }
5984
5985        // Clean-up disabled broadcast receivers.
5986        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5987            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5988                    packageName, disabledClasses, userId, true);
5989        }
5990
5991    }
5992
5993    final boolean clearBroadcastQueueForUserLocked(int userId) {
5994        boolean didSomething = false;
5995        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5996            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5997                    null, null, userId, true);
5998        }
5999        return didSomething;
6000    }
6001
6002    final boolean forceStopPackageLocked(String packageName, int appId,
6003            boolean callerWillRestart, boolean purgeCache, boolean doit,
6004            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6005        int i;
6006
6007        if (userId == UserHandle.USER_ALL && packageName == null) {
6008            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6009        }
6010
6011        if (appId < 0 && packageName != null) {
6012            try {
6013                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6014                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6015            } catch (RemoteException e) {
6016            }
6017        }
6018
6019        if (doit) {
6020            if (packageName != null) {
6021                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6022                        + " user=" + userId + ": " + reason);
6023            } else {
6024                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6025            }
6026
6027            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6028        }
6029
6030        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6031                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6032                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6033
6034        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6035                packageName, null, doit, evenPersistent, userId)) {
6036            if (!doit) {
6037                return true;
6038            }
6039            didSomething = true;
6040        }
6041
6042        if (mServices.bringDownDisabledPackageServicesLocked(
6043                packageName, null, userId, evenPersistent, true, doit)) {
6044            if (!doit) {
6045                return true;
6046            }
6047            didSomething = true;
6048        }
6049
6050        if (packageName == null) {
6051            // Remove all sticky broadcasts from this user.
6052            mStickyBroadcasts.remove(userId);
6053        }
6054
6055        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6056        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6057                userId, providers)) {
6058            if (!doit) {
6059                return true;
6060            }
6061            didSomething = true;
6062        }
6063        for (i = providers.size() - 1; i >= 0; i--) {
6064            removeDyingProviderLocked(null, providers.get(i), true);
6065        }
6066
6067        // Remove transient permissions granted from/to this package/user
6068        removeUriPermissionsForPackageLocked(packageName, userId, false);
6069
6070        if (doit) {
6071            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6072                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6073                        packageName, null, userId, doit);
6074            }
6075        }
6076
6077        if (packageName == null || uninstalling) {
6078            // Remove pending intents.  For now we only do this when force
6079            // stopping users, because we have some problems when doing this
6080            // for packages -- app widgets are not currently cleaned up for
6081            // such packages, so they can be left with bad pending intents.
6082            if (mIntentSenderRecords.size() > 0) {
6083                Iterator<WeakReference<PendingIntentRecord>> it
6084                        = mIntentSenderRecords.values().iterator();
6085                while (it.hasNext()) {
6086                    WeakReference<PendingIntentRecord> wpir = it.next();
6087                    if (wpir == null) {
6088                        it.remove();
6089                        continue;
6090                    }
6091                    PendingIntentRecord pir = wpir.get();
6092                    if (pir == null) {
6093                        it.remove();
6094                        continue;
6095                    }
6096                    if (packageName == null) {
6097                        // Stopping user, remove all objects for the user.
6098                        if (pir.key.userId != userId) {
6099                            // Not the same user, skip it.
6100                            continue;
6101                        }
6102                    } else {
6103                        if (UserHandle.getAppId(pir.uid) != appId) {
6104                            // Different app id, skip it.
6105                            continue;
6106                        }
6107                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6108                            // Different user, skip it.
6109                            continue;
6110                        }
6111                        if (!pir.key.packageName.equals(packageName)) {
6112                            // Different package, skip it.
6113                            continue;
6114                        }
6115                    }
6116                    if (!doit) {
6117                        return true;
6118                    }
6119                    didSomething = true;
6120                    it.remove();
6121                    pir.canceled = true;
6122                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6123                        pir.key.activity.pendingResults.remove(pir.ref);
6124                    }
6125                }
6126            }
6127        }
6128
6129        if (doit) {
6130            if (purgeCache && packageName != null) {
6131                AttributeCache ac = AttributeCache.instance();
6132                if (ac != null) {
6133                    ac.removePackage(packageName);
6134                }
6135            }
6136            if (mBooted) {
6137                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6138                mStackSupervisor.scheduleIdleLocked();
6139            }
6140        }
6141
6142        return didSomething;
6143    }
6144
6145    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6146        ProcessRecord old = mProcessNames.remove(name, uid);
6147        if (old != null) {
6148            old.uidRecord.numProcs--;
6149            if (old.uidRecord.numProcs == 0) {
6150                // No more processes using this uid, tell clients it is gone.
6151                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6152                        "No more processes in " + old.uidRecord);
6153                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6154                mActiveUids.remove(uid);
6155                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6156            }
6157            old.uidRecord = null;
6158        }
6159        mIsolatedProcesses.remove(uid);
6160        return old;
6161    }
6162
6163    private final void addProcessNameLocked(ProcessRecord proc) {
6164        // We shouldn't already have a process under this name, but just in case we
6165        // need to clean up whatever may be there now.
6166        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6167        if (old == proc && proc.persistent) {
6168            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6169            Slog.w(TAG, "Re-adding persistent process " + proc);
6170        } else if (old != null) {
6171            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6172        }
6173        UidRecord uidRec = mActiveUids.get(proc.uid);
6174        if (uidRec == null) {
6175            uidRec = new UidRecord(proc.uid);
6176            // This is the first appearance of the uid, report it now!
6177            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6178                    "Creating new process uid: " + uidRec);
6179            mActiveUids.put(proc.uid, uidRec);
6180            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6181            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6182        }
6183        proc.uidRecord = uidRec;
6184        uidRec.numProcs++;
6185        mProcessNames.put(proc.processName, proc.uid, proc);
6186        if (proc.isolated) {
6187            mIsolatedProcesses.put(proc.uid, proc);
6188        }
6189    }
6190
6191    boolean removeProcessLocked(ProcessRecord app,
6192            boolean callerWillRestart, boolean allowRestart, String reason) {
6193        final String name = app.processName;
6194        final int uid = app.uid;
6195        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6196            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6197
6198        ProcessRecord old = mProcessNames.get(name, uid);
6199        if (old != app) {
6200            // This process is no longer active, so nothing to do.
6201            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6202            return false;
6203        }
6204        removeProcessNameLocked(name, uid);
6205        if (mHeavyWeightProcess == app) {
6206            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6207                    mHeavyWeightProcess.userId, 0));
6208            mHeavyWeightProcess = null;
6209        }
6210        boolean needRestart = false;
6211        if (app.pid > 0 && app.pid != MY_PID) {
6212            int pid = app.pid;
6213            synchronized (mPidsSelfLocked) {
6214                mPidsSelfLocked.remove(pid);
6215                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6216            }
6217            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6218            if (app.isolated) {
6219                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6220            }
6221            boolean willRestart = false;
6222            if (app.persistent && !app.isolated) {
6223                if (!callerWillRestart) {
6224                    willRestart = true;
6225                } else {
6226                    needRestart = true;
6227                }
6228            }
6229            app.kill(reason, true);
6230            handleAppDiedLocked(app, willRestart, allowRestart);
6231            if (willRestart) {
6232                removeLruProcessLocked(app);
6233                addAppLocked(app.info, false, null /* ABI override */);
6234            }
6235        } else {
6236            mRemovedProcesses.add(app);
6237        }
6238
6239        return needRestart;
6240    }
6241
6242    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6243        cleanupAppInLaunchingProvidersLocked(app, true);
6244        removeProcessLocked(app, false, true, "timeout publishing content providers");
6245    }
6246
6247    private final void processStartTimedOutLocked(ProcessRecord app) {
6248        final int pid = app.pid;
6249        boolean gone = false;
6250        synchronized (mPidsSelfLocked) {
6251            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6252            if (knownApp != null && knownApp.thread == null) {
6253                mPidsSelfLocked.remove(pid);
6254                gone = true;
6255            }
6256        }
6257
6258        if (gone) {
6259            Slog.w(TAG, "Process " + app + " failed to attach");
6260            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6261                    pid, app.uid, app.processName);
6262            removeProcessNameLocked(app.processName, app.uid);
6263            if (mHeavyWeightProcess == app) {
6264                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6265                        mHeavyWeightProcess.userId, 0));
6266                mHeavyWeightProcess = null;
6267            }
6268            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6269            if (app.isolated) {
6270                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6271            }
6272            // Take care of any launching providers waiting for this process.
6273            cleanupAppInLaunchingProvidersLocked(app, true);
6274            // Take care of any services that are waiting for the process.
6275            mServices.processStartTimedOutLocked(app);
6276            app.kill("start timeout", true);
6277            removeLruProcessLocked(app);
6278            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6279                Slog.w(TAG, "Unattached app died before backup, skipping");
6280                try {
6281                    IBackupManager bm = IBackupManager.Stub.asInterface(
6282                            ServiceManager.getService(Context.BACKUP_SERVICE));
6283                    bm.agentDisconnected(app.info.packageName);
6284                } catch (RemoteException e) {
6285                    // Can't happen; the backup manager is local
6286                }
6287            }
6288            if (isPendingBroadcastProcessLocked(pid)) {
6289                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6290                skipPendingBroadcastLocked(pid);
6291            }
6292        } else {
6293            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6294        }
6295    }
6296
6297    private final boolean attachApplicationLocked(IApplicationThread thread,
6298            int pid) {
6299
6300        // Find the application record that is being attached...  either via
6301        // the pid if we are running in multiple processes, or just pull the
6302        // next app record if we are emulating process with anonymous threads.
6303        ProcessRecord app;
6304        if (pid != MY_PID && pid >= 0) {
6305            synchronized (mPidsSelfLocked) {
6306                app = mPidsSelfLocked.get(pid);
6307            }
6308        } else {
6309            app = null;
6310        }
6311
6312        if (app == null) {
6313            Slog.w(TAG, "No pending application record for pid " + pid
6314                    + " (IApplicationThread " + thread + "); dropping process");
6315            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6316            if (pid > 0 && pid != MY_PID) {
6317                Process.killProcessQuiet(pid);
6318                //TODO: killProcessGroup(app.info.uid, pid);
6319            } else {
6320                try {
6321                    thread.scheduleExit();
6322                } catch (Exception e) {
6323                    // Ignore exceptions.
6324                }
6325            }
6326            return false;
6327        }
6328
6329        // If this application record is still attached to a previous
6330        // process, clean it up now.
6331        if (app.thread != null) {
6332            handleAppDiedLocked(app, true, true);
6333        }
6334
6335        // Tell the process all about itself.
6336
6337        if (DEBUG_ALL) Slog.v(
6338                TAG, "Binding process pid " + pid + " to record " + app);
6339
6340        final String processName = app.processName;
6341        try {
6342            AppDeathRecipient adr = new AppDeathRecipient(
6343                    app, pid, thread);
6344            thread.asBinder().linkToDeath(adr, 0);
6345            app.deathRecipient = adr;
6346        } catch (RemoteException e) {
6347            app.resetPackageList(mProcessStats);
6348            startProcessLocked(app, "link fail", processName);
6349            return false;
6350        }
6351
6352        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6353
6354        app.makeActive(thread, mProcessStats);
6355        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6356        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6357        app.forcingToForeground = null;
6358        updateProcessForegroundLocked(app, false, false);
6359        app.hasShownUi = false;
6360        app.debugging = false;
6361        app.cached = false;
6362        app.killedByAm = false;
6363
6364        // We carefully use the same state that PackageManager uses for
6365        // filtering, since we use this flag to decide if we need to install
6366        // providers when user is unlocked later
6367        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6368
6369        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6370
6371        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6372        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6373
6374        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6375            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6376            msg.obj = app;
6377            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6378        }
6379
6380        if (!normalMode) {
6381            Slog.i(TAG, "Launching preboot mode app: " + app);
6382        }
6383
6384        if (DEBUG_ALL) Slog.v(
6385            TAG, "New app record " + app
6386            + " thread=" + thread.asBinder() + " pid=" + pid);
6387        try {
6388            int testMode = IApplicationThread.DEBUG_OFF;
6389            if (mDebugApp != null && mDebugApp.equals(processName)) {
6390                testMode = mWaitForDebugger
6391                    ? IApplicationThread.DEBUG_WAIT
6392                    : IApplicationThread.DEBUG_ON;
6393                app.debugging = true;
6394                if (mDebugTransient) {
6395                    mDebugApp = mOrigDebugApp;
6396                    mWaitForDebugger = mOrigWaitForDebugger;
6397                }
6398            }
6399            String profileFile = app.instrumentationProfileFile;
6400            ParcelFileDescriptor profileFd = null;
6401            int samplingInterval = 0;
6402            boolean profileAutoStop = false;
6403            if (mProfileApp != null && mProfileApp.equals(processName)) {
6404                mProfileProc = app;
6405                profileFile = mProfileFile;
6406                profileFd = mProfileFd;
6407                samplingInterval = mSamplingInterval;
6408                profileAutoStop = mAutoStopProfiler;
6409            }
6410            boolean enableTrackAllocation = false;
6411            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6412                enableTrackAllocation = true;
6413                mTrackAllocationApp = null;
6414            }
6415
6416            // If the app is being launched for restore or full backup, set it up specially
6417            boolean isRestrictedBackupMode = false;
6418            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6419                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6420                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6421                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6422                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6423            }
6424
6425            if (app.instrumentationClass != null) {
6426                notifyPackageUse(app.instrumentationClass.getPackageName(),
6427                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6428            }
6429            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6430                    + processName + " with config " + mConfiguration);
6431            ApplicationInfo appInfo = app.instrumentationInfo != null
6432                    ? app.instrumentationInfo : app.info;
6433            app.compat = compatibilityInfoForPackageLocked(appInfo);
6434            if (profileFd != null) {
6435                profileFd = profileFd.dup();
6436            }
6437            ProfilerInfo profilerInfo = profileFile == null ? null
6438                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6439            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6440                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6441                    app.instrumentationUiAutomationConnection, testMode,
6442                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6443                    isRestrictedBackupMode || !normalMode, app.persistent,
6444                    new Configuration(mConfiguration), app.compat,
6445                    getCommonServicesLocked(app.isolated),
6446                    mCoreSettingsObserver.getCoreSettingsLocked());
6447            updateLruProcessLocked(app, false, null);
6448            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6449        } catch (Exception e) {
6450            // todo: Yikes!  What should we do?  For now we will try to
6451            // start another process, but that could easily get us in
6452            // an infinite loop of restarting processes...
6453            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6454
6455            app.resetPackageList(mProcessStats);
6456            app.unlinkDeathRecipient();
6457            startProcessLocked(app, "bind fail", processName);
6458            return false;
6459        }
6460
6461        // Remove this record from the list of starting applications.
6462        mPersistentStartingProcesses.remove(app);
6463        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6464                "Attach application locked removing on hold: " + app);
6465        mProcessesOnHold.remove(app);
6466
6467        boolean badApp = false;
6468        boolean didSomething = false;
6469
6470        // See if the top visible activity is waiting to run in this process...
6471        if (normalMode) {
6472            try {
6473                if (mStackSupervisor.attachApplicationLocked(app)) {
6474                    didSomething = true;
6475                }
6476            } catch (Exception e) {
6477                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6478                badApp = true;
6479            }
6480        }
6481
6482        // Find any services that should be running in this process...
6483        if (!badApp) {
6484            try {
6485                didSomething |= mServices.attachApplicationLocked(app, processName);
6486            } catch (Exception e) {
6487                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6488                badApp = true;
6489            }
6490        }
6491
6492        // Check if a next-broadcast receiver is in this process...
6493        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6494            try {
6495                didSomething |= sendPendingBroadcastsLocked(app);
6496            } catch (Exception e) {
6497                // If the app died trying to launch the receiver we declare it 'bad'
6498                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6499                badApp = true;
6500            }
6501        }
6502
6503        // Check whether the next backup agent is in this process...
6504        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6505            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6506                    "New app is backup target, launching agent for " + app);
6507            notifyPackageUse(mBackupTarget.appInfo.packageName,
6508                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6509            try {
6510                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6511                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6512                        mBackupTarget.backupMode);
6513            } catch (Exception e) {
6514                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6515                badApp = true;
6516            }
6517        }
6518
6519        if (badApp) {
6520            app.kill("error during init", true);
6521            handleAppDiedLocked(app, false, true);
6522            return false;
6523        }
6524
6525        if (!didSomething) {
6526            updateOomAdjLocked();
6527        }
6528
6529        return true;
6530    }
6531
6532    @Override
6533    public final void attachApplication(IApplicationThread thread) {
6534        synchronized (this) {
6535            int callingPid = Binder.getCallingPid();
6536            final long origId = Binder.clearCallingIdentity();
6537            attachApplicationLocked(thread, callingPid);
6538            Binder.restoreCallingIdentity(origId);
6539        }
6540    }
6541
6542    @Override
6543    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6544        final long origId = Binder.clearCallingIdentity();
6545        synchronized (this) {
6546            ActivityStack stack = ActivityRecord.getStackLocked(token);
6547            if (stack != null) {
6548                ActivityRecord r =
6549                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6550                if (stopProfiling) {
6551                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6552                        try {
6553                            mProfileFd.close();
6554                        } catch (IOException e) {
6555                        }
6556                        clearProfilerLocked();
6557                    }
6558                }
6559            }
6560        }
6561        Binder.restoreCallingIdentity(origId);
6562    }
6563
6564    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6565        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6566                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6567    }
6568
6569    void enableScreenAfterBoot() {
6570        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6571                SystemClock.uptimeMillis());
6572        mWindowManager.enableScreenAfterBoot();
6573
6574        synchronized (this) {
6575            updateEventDispatchingLocked();
6576        }
6577    }
6578
6579    @Override
6580    public void showBootMessage(final CharSequence msg, final boolean always) {
6581        if (Binder.getCallingUid() != Process.myUid()) {
6582            // These days only the core system can call this, so apps can't get in
6583            // the way of what we show about running them.
6584        }
6585        mWindowManager.showBootMessage(msg, always);
6586    }
6587
6588    @Override
6589    public void keyguardWaitingForActivityDrawn() {
6590        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6591        final long token = Binder.clearCallingIdentity();
6592        try {
6593            synchronized (this) {
6594                if (DEBUG_LOCKSCREEN) logLockScreen("");
6595                mWindowManager.keyguardWaitingForActivityDrawn();
6596                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6597                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6598                    updateSleepIfNeededLocked();
6599                }
6600            }
6601        } finally {
6602            Binder.restoreCallingIdentity(token);
6603        }
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                if (DEBUG_LOCKSCREEN) logLockScreen("");
6613                mWindowManager.keyguardGoingAway(flags);
6614                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6615                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6616                    updateSleepIfNeededLocked();
6617
6618                    // Some stack visibility might change (e.g. docked stack)
6619                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6620                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6621                }
6622            }
6623        } finally {
6624            Binder.restoreCallingIdentity(token);
6625        }
6626    }
6627
6628    final void finishBooting() {
6629        synchronized (this) {
6630            if (!mBootAnimationComplete) {
6631                mCallFinishBooting = true;
6632                return;
6633            }
6634            mCallFinishBooting = false;
6635        }
6636
6637        ArraySet<String> completedIsas = new ArraySet<String>();
6638        for (String abi : Build.SUPPORTED_ABIS) {
6639            Process.establishZygoteConnectionForAbi(abi);
6640            final String instructionSet = VMRuntime.getInstructionSet(abi);
6641            if (!completedIsas.contains(instructionSet)) {
6642                try {
6643                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6644                } catch (InstallerException e) {
6645                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6646                            e.getMessage() +")");
6647                }
6648                completedIsas.add(instructionSet);
6649            }
6650        }
6651
6652        IntentFilter pkgFilter = new IntentFilter();
6653        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6654        pkgFilter.addDataScheme("package");
6655        mContext.registerReceiver(new BroadcastReceiver() {
6656            @Override
6657            public void onReceive(Context context, Intent intent) {
6658                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6659                if (pkgs != null) {
6660                    for (String pkg : pkgs) {
6661                        synchronized (ActivityManagerService.this) {
6662                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6663                                    0, "query restart")) {
6664                                setResultCode(Activity.RESULT_OK);
6665                                return;
6666                            }
6667                        }
6668                    }
6669                }
6670            }
6671        }, pkgFilter);
6672
6673        IntentFilter dumpheapFilter = new IntentFilter();
6674        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6675        mContext.registerReceiver(new BroadcastReceiver() {
6676            @Override
6677            public void onReceive(Context context, Intent intent) {
6678                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6679                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6680                } else {
6681                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6682                }
6683            }
6684        }, dumpheapFilter);
6685
6686        // Let system services know.
6687        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6688
6689        synchronized (this) {
6690            // Ensure that any processes we had put on hold are now started
6691            // up.
6692            final int NP = mProcessesOnHold.size();
6693            if (NP > 0) {
6694                ArrayList<ProcessRecord> procs =
6695                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6696                for (int ip=0; ip<NP; ip++) {
6697                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6698                            + procs.get(ip));
6699                    startProcessLocked(procs.get(ip), "on-hold", null);
6700                }
6701            }
6702
6703            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6704                // Start looking for apps that are abusing wake locks.
6705                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6706                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6707                // Tell anyone interested that we are done booting!
6708                SystemProperties.set("sys.boot_completed", "1");
6709
6710                // And trigger dev.bootcomplete if we are not showing encryption progress
6711                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6712                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6713                    SystemProperties.set("dev.bootcomplete", "1");
6714                }
6715                mUserController.sendBootCompletedLocked(
6716                        new IIntentReceiver.Stub() {
6717                            @Override
6718                            public void performReceive(Intent intent, int resultCode,
6719                                    String data, Bundle extras, boolean ordered,
6720                                    boolean sticky, int sendingUser) {
6721                                synchronized (ActivityManagerService.this) {
6722                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6723                                            true, false);
6724                                }
6725                            }
6726                        });
6727                scheduleStartProfilesLocked();
6728            }
6729        }
6730    }
6731
6732    @Override
6733    public void bootAnimationComplete() {
6734        final boolean callFinishBooting;
6735        synchronized (this) {
6736            callFinishBooting = mCallFinishBooting;
6737            mBootAnimationComplete = true;
6738        }
6739        if (callFinishBooting) {
6740            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6741            finishBooting();
6742            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6743        }
6744    }
6745
6746    final void ensureBootCompleted() {
6747        boolean booting;
6748        boolean enableScreen;
6749        synchronized (this) {
6750            booting = mBooting;
6751            mBooting = false;
6752            enableScreen = !mBooted;
6753            mBooted = true;
6754        }
6755
6756        if (booting) {
6757            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6758            finishBooting();
6759            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6760        }
6761
6762        if (enableScreen) {
6763            enableScreenAfterBoot();
6764        }
6765    }
6766
6767    @Override
6768    public final void activityResumed(IBinder token) {
6769        final long origId = Binder.clearCallingIdentity();
6770        synchronized(this) {
6771            ActivityStack stack = ActivityRecord.getStackLocked(token);
6772            if (stack != null) {
6773                stack.activityResumedLocked(token);
6774            }
6775        }
6776        Binder.restoreCallingIdentity(origId);
6777    }
6778
6779    @Override
6780    public final void activityPaused(IBinder token) {
6781        final long origId = Binder.clearCallingIdentity();
6782        synchronized(this) {
6783            ActivityStack stack = ActivityRecord.getStackLocked(token);
6784            if (stack != null) {
6785                stack.activityPausedLocked(token, false);
6786            }
6787        }
6788        Binder.restoreCallingIdentity(origId);
6789    }
6790
6791    @Override
6792    public final void activityStopped(IBinder token, Bundle icicle,
6793            PersistableBundle persistentState, CharSequence description) {
6794        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6795
6796        // Refuse possible leaked file descriptors
6797        if (icicle != null && icicle.hasFileDescriptors()) {
6798            throw new IllegalArgumentException("File descriptors passed in Bundle");
6799        }
6800
6801        final long origId = Binder.clearCallingIdentity();
6802
6803        synchronized (this) {
6804            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6805            if (r != null) {
6806                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6807            }
6808        }
6809
6810        trimApplications();
6811
6812        Binder.restoreCallingIdentity(origId);
6813    }
6814
6815    @Override
6816    public final void activityDestroyed(IBinder token) {
6817        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6818        synchronized (this) {
6819            ActivityStack stack = ActivityRecord.getStackLocked(token);
6820            if (stack != null) {
6821                stack.activityDestroyedLocked(token, "activityDestroyed");
6822            }
6823        }
6824    }
6825
6826    @Override
6827    public final void activityRelaunched(IBinder token) {
6828        final long origId = Binder.clearCallingIdentity();
6829        synchronized (this) {
6830            mStackSupervisor.activityRelaunchedLocked(token);
6831        }
6832        Binder.restoreCallingIdentity(origId);
6833    }
6834
6835    @Override
6836    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6837            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6838        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6839                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6840        synchronized (this) {
6841            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6842            if (record == null) {
6843                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6844                        + "found for: " + token);
6845            }
6846            record.setSizeConfigurations(horizontalSizeConfiguration,
6847                    verticalSizeConfigurations, smallestSizeConfigurations);
6848        }
6849    }
6850
6851    @Override
6852    public final void backgroundResourcesReleased(IBinder token) {
6853        final long origId = Binder.clearCallingIdentity();
6854        try {
6855            synchronized (this) {
6856                ActivityStack stack = ActivityRecord.getStackLocked(token);
6857                if (stack != null) {
6858                    stack.backgroundResourcesReleased();
6859                }
6860            }
6861        } finally {
6862            Binder.restoreCallingIdentity(origId);
6863        }
6864    }
6865
6866    @Override
6867    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6868        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6869    }
6870
6871    @Override
6872    public final void notifyEnterAnimationComplete(IBinder token) {
6873        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6874    }
6875
6876    @Override
6877    public String getCallingPackage(IBinder token) {
6878        synchronized (this) {
6879            ActivityRecord r = getCallingRecordLocked(token);
6880            return r != null ? r.info.packageName : null;
6881        }
6882    }
6883
6884    @Override
6885    public ComponentName getCallingActivity(IBinder token) {
6886        synchronized (this) {
6887            ActivityRecord r = getCallingRecordLocked(token);
6888            return r != null ? r.intent.getComponent() : null;
6889        }
6890    }
6891
6892    private ActivityRecord getCallingRecordLocked(IBinder token) {
6893        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6894        if (r == null) {
6895            return null;
6896        }
6897        return r.resultTo;
6898    }
6899
6900    @Override
6901    public ComponentName getActivityClassForToken(IBinder token) {
6902        synchronized(this) {
6903            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6904            if (r == null) {
6905                return null;
6906            }
6907            return r.intent.getComponent();
6908        }
6909    }
6910
6911    @Override
6912    public String getPackageForToken(IBinder token) {
6913        synchronized(this) {
6914            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6915            if (r == null) {
6916                return null;
6917            }
6918            return r.packageName;
6919        }
6920    }
6921
6922    @Override
6923    public boolean isRootVoiceInteraction(IBinder token) {
6924        synchronized(this) {
6925            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6926            if (r == null) {
6927                return false;
6928            }
6929            return r.rootVoiceInteraction;
6930        }
6931    }
6932
6933    @Override
6934    public IIntentSender getIntentSender(int type,
6935            String packageName, IBinder token, String resultWho,
6936            int requestCode, Intent[] intents, String[] resolvedTypes,
6937            int flags, Bundle bOptions, int userId) {
6938        enforceNotIsolatedCaller("getIntentSender");
6939        // Refuse possible leaked file descriptors
6940        if (intents != null) {
6941            if (intents.length < 1) {
6942                throw new IllegalArgumentException("Intents array length must be >= 1");
6943            }
6944            for (int i=0; i<intents.length; i++) {
6945                Intent intent = intents[i];
6946                if (intent != null) {
6947                    if (intent.hasFileDescriptors()) {
6948                        throw new IllegalArgumentException("File descriptors passed in Intent");
6949                    }
6950                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6951                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6952                        throw new IllegalArgumentException(
6953                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6954                    }
6955                    intents[i] = new Intent(intent);
6956                }
6957            }
6958            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6959                throw new IllegalArgumentException(
6960                        "Intent array length does not match resolvedTypes length");
6961            }
6962        }
6963        if (bOptions != null) {
6964            if (bOptions.hasFileDescriptors()) {
6965                throw new IllegalArgumentException("File descriptors passed in options");
6966            }
6967        }
6968
6969        synchronized(this) {
6970            int callingUid = Binder.getCallingUid();
6971            int origUserId = userId;
6972            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6973                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6974                    ALLOW_NON_FULL, "getIntentSender", null);
6975            if (origUserId == UserHandle.USER_CURRENT) {
6976                // We don't want to evaluate this until the pending intent is
6977                // actually executed.  However, we do want to always do the
6978                // security checking for it above.
6979                userId = UserHandle.USER_CURRENT;
6980            }
6981            try {
6982                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6983                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6984                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6985                    if (!UserHandle.isSameApp(callingUid, uid)) {
6986                        String msg = "Permission Denial: getIntentSender() from pid="
6987                            + Binder.getCallingPid()
6988                            + ", uid=" + Binder.getCallingUid()
6989                            + ", (need uid=" + uid + ")"
6990                            + " is not allowed to send as package " + packageName;
6991                        Slog.w(TAG, msg);
6992                        throw new SecurityException(msg);
6993                    }
6994                }
6995
6996                return getIntentSenderLocked(type, packageName, callingUid, userId,
6997                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6998
6999            } catch (RemoteException e) {
7000                throw new SecurityException(e);
7001            }
7002        }
7003    }
7004
7005    IIntentSender getIntentSenderLocked(int type, String packageName,
7006            int callingUid, int userId, IBinder token, String resultWho,
7007            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7008            Bundle bOptions) {
7009        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7010        ActivityRecord activity = null;
7011        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7012            activity = ActivityRecord.isInStackLocked(token);
7013            if (activity == null) {
7014                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7015                return null;
7016            }
7017            if (activity.finishing) {
7018                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7019                return null;
7020            }
7021        }
7022
7023        // We're going to be splicing together extras before sending, so we're
7024        // okay poking into any contained extras.
7025        if (intents != null) {
7026            for (int i = 0; i < intents.length; i++) {
7027                intents[i].setDefusable(true);
7028            }
7029        }
7030        Bundle.setDefusable(bOptions, true);
7031
7032        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7033        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7034        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7035        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7036                |PendingIntent.FLAG_UPDATE_CURRENT);
7037
7038        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7039                type, packageName, activity, resultWho,
7040                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7041        WeakReference<PendingIntentRecord> ref;
7042        ref = mIntentSenderRecords.get(key);
7043        PendingIntentRecord rec = ref != null ? ref.get() : null;
7044        if (rec != null) {
7045            if (!cancelCurrent) {
7046                if (updateCurrent) {
7047                    if (rec.key.requestIntent != null) {
7048                        rec.key.requestIntent.replaceExtras(intents != null ?
7049                                intents[intents.length - 1] : null);
7050                    }
7051                    if (intents != null) {
7052                        intents[intents.length-1] = rec.key.requestIntent;
7053                        rec.key.allIntents = intents;
7054                        rec.key.allResolvedTypes = resolvedTypes;
7055                    } else {
7056                        rec.key.allIntents = null;
7057                        rec.key.allResolvedTypes = null;
7058                    }
7059                }
7060                return rec;
7061            }
7062            rec.canceled = true;
7063            mIntentSenderRecords.remove(key);
7064        }
7065        if (noCreate) {
7066            return rec;
7067        }
7068        rec = new PendingIntentRecord(this, key, callingUid);
7069        mIntentSenderRecords.put(key, rec.ref);
7070        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7071            if (activity.pendingResults == null) {
7072                activity.pendingResults
7073                        = new HashSet<WeakReference<PendingIntentRecord>>();
7074            }
7075            activity.pendingResults.add(rec.ref);
7076        }
7077        return rec;
7078    }
7079
7080    @Override
7081    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7082            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7083        if (target instanceof PendingIntentRecord) {
7084            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7085                    finishedReceiver, requiredPermission, options);
7086        } else {
7087            if (intent == null) {
7088                // Weird case: someone has given us their own custom IIntentSender, and now
7089                // they have someone else trying to send to it but of course this isn't
7090                // really a PendingIntent, so there is no base Intent, and the caller isn't
7091                // supplying an Intent... but we never want to dispatch a null Intent to
7092                // a receiver, so um...  let's make something up.
7093                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7094                intent = new Intent(Intent.ACTION_MAIN);
7095            }
7096            try {
7097                target.send(code, intent, resolvedType, null, requiredPermission, options);
7098            } catch (RemoteException e) {
7099            }
7100            // Platform code can rely on getting a result back when the send is done, but if
7101            // this intent sender is from outside of the system we can't rely on it doing that.
7102            // So instead we don't give it the result receiver, and instead just directly
7103            // report the finish immediately.
7104            if (finishedReceiver != null) {
7105                try {
7106                    finishedReceiver.performReceive(intent, 0,
7107                            null, null, false, false, UserHandle.getCallingUserId());
7108                } catch (RemoteException e) {
7109                }
7110            }
7111            return 0;
7112        }
7113    }
7114
7115    @Override
7116    public void cancelIntentSender(IIntentSender sender) {
7117        if (!(sender instanceof PendingIntentRecord)) {
7118            return;
7119        }
7120        synchronized(this) {
7121            PendingIntentRecord rec = (PendingIntentRecord)sender;
7122            try {
7123                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7124                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7125                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7126                    String msg = "Permission Denial: cancelIntentSender() from pid="
7127                        + Binder.getCallingPid()
7128                        + ", uid=" + Binder.getCallingUid()
7129                        + " is not allowed to cancel packges "
7130                        + rec.key.packageName;
7131                    Slog.w(TAG, msg);
7132                    throw new SecurityException(msg);
7133                }
7134            } catch (RemoteException e) {
7135                throw new SecurityException(e);
7136            }
7137            cancelIntentSenderLocked(rec, true);
7138        }
7139    }
7140
7141    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7142        rec.canceled = true;
7143        mIntentSenderRecords.remove(rec.key);
7144        if (cleanActivity && rec.key.activity != null) {
7145            rec.key.activity.pendingResults.remove(rec.ref);
7146        }
7147    }
7148
7149    @Override
7150    public String getPackageForIntentSender(IIntentSender pendingResult) {
7151        if (!(pendingResult instanceof PendingIntentRecord)) {
7152            return null;
7153        }
7154        try {
7155            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7156            return res.key.packageName;
7157        } catch (ClassCastException e) {
7158        }
7159        return null;
7160    }
7161
7162    @Override
7163    public int getUidForIntentSender(IIntentSender sender) {
7164        if (sender instanceof PendingIntentRecord) {
7165            try {
7166                PendingIntentRecord res = (PendingIntentRecord)sender;
7167                return res.uid;
7168            } catch (ClassCastException e) {
7169            }
7170        }
7171        return -1;
7172    }
7173
7174    @Override
7175    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7176        if (!(pendingResult instanceof PendingIntentRecord)) {
7177            return false;
7178        }
7179        try {
7180            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7181            if (res.key.allIntents == null) {
7182                return false;
7183            }
7184            for (int i=0; i<res.key.allIntents.length; i++) {
7185                Intent intent = res.key.allIntents[i];
7186                if (intent.getPackage() != null && intent.getComponent() != null) {
7187                    return false;
7188                }
7189            }
7190            return true;
7191        } catch (ClassCastException e) {
7192        }
7193        return false;
7194    }
7195
7196    @Override
7197    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7198        if (!(pendingResult instanceof PendingIntentRecord)) {
7199            return false;
7200        }
7201        try {
7202            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7203            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7204                return true;
7205            }
7206            return false;
7207        } catch (ClassCastException e) {
7208        }
7209        return false;
7210    }
7211
7212    @Override
7213    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7214        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7215                "getIntentForIntentSender()");
7216        if (!(pendingResult instanceof PendingIntentRecord)) {
7217            return null;
7218        }
7219        try {
7220            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7221            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7222        } catch (ClassCastException e) {
7223        }
7224        return null;
7225    }
7226
7227    @Override
7228    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7229        if (!(pendingResult instanceof PendingIntentRecord)) {
7230            return null;
7231        }
7232        try {
7233            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7234            synchronized (this) {
7235                return getTagForIntentSenderLocked(res, prefix);
7236            }
7237        } catch (ClassCastException e) {
7238        }
7239        return null;
7240    }
7241
7242    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7243        final Intent intent = res.key.requestIntent;
7244        if (intent != null) {
7245            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7246                    || res.lastTagPrefix.equals(prefix))) {
7247                return res.lastTag;
7248            }
7249            res.lastTagPrefix = prefix;
7250            final StringBuilder sb = new StringBuilder(128);
7251            if (prefix != null) {
7252                sb.append(prefix);
7253            }
7254            if (intent.getAction() != null) {
7255                sb.append(intent.getAction());
7256            } else if (intent.getComponent() != null) {
7257                intent.getComponent().appendShortString(sb);
7258            } else {
7259                sb.append("?");
7260            }
7261            return res.lastTag = sb.toString();
7262        }
7263        return null;
7264    }
7265
7266    @Override
7267    public void setProcessLimit(int max) {
7268        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7269                "setProcessLimit()");
7270        synchronized (this) {
7271            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7272            mProcessLimitOverride = max;
7273        }
7274        trimApplications();
7275    }
7276
7277    @Override
7278    public int getProcessLimit() {
7279        synchronized (this) {
7280            return mProcessLimitOverride;
7281        }
7282    }
7283
7284    void foregroundTokenDied(ForegroundToken token) {
7285        synchronized (ActivityManagerService.this) {
7286            synchronized (mPidsSelfLocked) {
7287                ForegroundToken cur
7288                    = mForegroundProcesses.get(token.pid);
7289                if (cur != token) {
7290                    return;
7291                }
7292                mForegroundProcesses.remove(token.pid);
7293                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7294                if (pr == null) {
7295                    return;
7296                }
7297                pr.forcingToForeground = null;
7298                updateProcessForegroundLocked(pr, false, false);
7299            }
7300            updateOomAdjLocked();
7301        }
7302    }
7303
7304    @Override
7305    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7306        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7307                "setProcessForeground()");
7308        synchronized(this) {
7309            boolean changed = false;
7310
7311            synchronized (mPidsSelfLocked) {
7312                ProcessRecord pr = mPidsSelfLocked.get(pid);
7313                if (pr == null && isForeground) {
7314                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7315                    return;
7316                }
7317                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7318                if (oldToken != null) {
7319                    oldToken.token.unlinkToDeath(oldToken, 0);
7320                    mForegroundProcesses.remove(pid);
7321                    if (pr != null) {
7322                        pr.forcingToForeground = null;
7323                    }
7324                    changed = true;
7325                }
7326                if (isForeground && token != null) {
7327                    ForegroundToken newToken = new ForegroundToken() {
7328                        @Override
7329                        public void binderDied() {
7330                            foregroundTokenDied(this);
7331                        }
7332                    };
7333                    newToken.pid = pid;
7334                    newToken.token = token;
7335                    try {
7336                        token.linkToDeath(newToken, 0);
7337                        mForegroundProcesses.put(pid, newToken);
7338                        pr.forcingToForeground = token;
7339                        changed = true;
7340                    } catch (RemoteException e) {
7341                        // If the process died while doing this, we will later
7342                        // do the cleanup with the process death link.
7343                    }
7344                }
7345            }
7346
7347            if (changed) {
7348                updateOomAdjLocked();
7349            }
7350        }
7351    }
7352
7353    @Override
7354    public boolean isAppForeground(int uid) throws RemoteException {
7355        synchronized (this) {
7356            UidRecord uidRec = mActiveUids.get(uid);
7357            if (uidRec == null || uidRec.idle) {
7358                return false;
7359            }
7360            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7361        }
7362    }
7363
7364    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7365    // be guarded by permission checking.
7366    int getUidState(int uid) {
7367        synchronized (this) {
7368            UidRecord uidRec = mActiveUids.get(uid);
7369            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7370        }
7371    }
7372
7373    @Override
7374    public boolean isInMultiWindowMode(IBinder token) {
7375        final long origId = Binder.clearCallingIdentity();
7376        try {
7377            synchronized(this) {
7378                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7379                if (r == null) {
7380                    return false;
7381                }
7382                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7383                return !r.task.mFullscreen;
7384            }
7385        } finally {
7386            Binder.restoreCallingIdentity(origId);
7387        }
7388    }
7389
7390    @Override
7391    public boolean isInPictureInPictureMode(IBinder token) {
7392        final long origId = Binder.clearCallingIdentity();
7393        try {
7394            synchronized(this) {
7395                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7396                if (stack == null) {
7397                    return false;
7398                }
7399                return stack.mStackId == PINNED_STACK_ID;
7400            }
7401        } finally {
7402            Binder.restoreCallingIdentity(origId);
7403        }
7404    }
7405
7406    @Override
7407    public void enterPictureInPictureMode(IBinder token) {
7408        final long origId = Binder.clearCallingIdentity();
7409        try {
7410            synchronized(this) {
7411                if (!mSupportsPictureInPicture) {
7412                    throw new IllegalStateException("enterPictureInPictureMode: "
7413                            + "Device doesn't support picture-in-picture mode.");
7414                }
7415
7416                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7417
7418                if (r == null) {
7419                    throw new IllegalStateException("enterPictureInPictureMode: "
7420                            + "Can't find activity for token=" + token);
7421                }
7422
7423                if (!r.supportsPictureInPicture()) {
7424                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7425                            + "Picture-In-Picture not supported for r=" + r);
7426                }
7427
7428                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7429                // current bounds.
7430                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7431                final Rect bounds = (pinnedStack != null)
7432                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7433
7434                mStackSupervisor.moveActivityToPinnedStackLocked(
7435                        r, "enterPictureInPictureMode", bounds);
7436            }
7437        } finally {
7438            Binder.restoreCallingIdentity(origId);
7439        }
7440    }
7441
7442    // =========================================================
7443    // PROCESS INFO
7444    // =========================================================
7445
7446    static class ProcessInfoService extends IProcessInfoService.Stub {
7447        final ActivityManagerService mActivityManagerService;
7448        ProcessInfoService(ActivityManagerService activityManagerService) {
7449            mActivityManagerService = activityManagerService;
7450        }
7451
7452        @Override
7453        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7454            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7455                    /*in*/ pids, /*out*/ states, null);
7456        }
7457
7458        @Override
7459        public void getProcessStatesAndOomScoresFromPids(
7460                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7461            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7462                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7463        }
7464    }
7465
7466    /**
7467     * For each PID in the given input array, write the current process state
7468     * for that process into the states array, or -1 to indicate that no
7469     * process with the given PID exists. If scores array is provided, write
7470     * the oom score for the process into the scores array, with INVALID_ADJ
7471     * indicating the PID doesn't exist.
7472     */
7473    public void getProcessStatesAndOomScoresForPIDs(
7474            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7475        if (scores != null) {
7476            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7477                    "getProcessStatesAndOomScoresForPIDs()");
7478        }
7479
7480        if (pids == null) {
7481            throw new NullPointerException("pids");
7482        } else if (states == null) {
7483            throw new NullPointerException("states");
7484        } else if (pids.length != states.length) {
7485            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7486        } else if (scores != null && pids.length != scores.length) {
7487            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7488        }
7489
7490        synchronized (mPidsSelfLocked) {
7491            for (int i = 0; i < pids.length; i++) {
7492                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7493                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7494                        pr.curProcState;
7495                if (scores != null) {
7496                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7497                }
7498            }
7499        }
7500    }
7501
7502    // =========================================================
7503    // PERMISSIONS
7504    // =========================================================
7505
7506    static class PermissionController extends IPermissionController.Stub {
7507        ActivityManagerService mActivityManagerService;
7508        PermissionController(ActivityManagerService activityManagerService) {
7509            mActivityManagerService = activityManagerService;
7510        }
7511
7512        @Override
7513        public boolean checkPermission(String permission, int pid, int uid) {
7514            return mActivityManagerService.checkPermission(permission, pid,
7515                    uid) == PackageManager.PERMISSION_GRANTED;
7516        }
7517
7518        @Override
7519        public String[] getPackagesForUid(int uid) {
7520            return mActivityManagerService.mContext.getPackageManager()
7521                    .getPackagesForUid(uid);
7522        }
7523
7524        @Override
7525        public boolean isRuntimePermission(String permission) {
7526            try {
7527                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7528                        .getPermissionInfo(permission, 0);
7529                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7530            } catch (NameNotFoundException nnfe) {
7531                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7532            }
7533            return false;
7534        }
7535    }
7536
7537    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7538        @Override
7539        public int checkComponentPermission(String permission, int pid, int uid,
7540                int owningUid, boolean exported) {
7541            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7542                    owningUid, exported);
7543        }
7544
7545        @Override
7546        public Object getAMSLock() {
7547            return ActivityManagerService.this;
7548        }
7549    }
7550
7551    /**
7552     * This can be called with or without the global lock held.
7553     */
7554    int checkComponentPermission(String permission, int pid, int uid,
7555            int owningUid, boolean exported) {
7556        if (pid == MY_PID) {
7557            return PackageManager.PERMISSION_GRANTED;
7558        }
7559        return ActivityManager.checkComponentPermission(permission, uid,
7560                owningUid, exported);
7561    }
7562
7563    /**
7564     * As the only public entry point for permissions checking, this method
7565     * can enforce the semantic that requesting a check on a null global
7566     * permission is automatically denied.  (Internally a null permission
7567     * string is used when calling {@link #checkComponentPermission} in cases
7568     * when only uid-based security is needed.)
7569     *
7570     * This can be called with or without the global lock held.
7571     */
7572    @Override
7573    public int checkPermission(String permission, int pid, int uid) {
7574        if (permission == null) {
7575            return PackageManager.PERMISSION_DENIED;
7576        }
7577        return checkComponentPermission(permission, pid, uid, -1, true);
7578    }
7579
7580    @Override
7581    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7582        if (permission == null) {
7583            return PackageManager.PERMISSION_DENIED;
7584        }
7585
7586        // We might be performing an operation on behalf of an indirect binder
7587        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7588        // client identity accordingly before proceeding.
7589        Identity tlsIdentity = sCallerIdentity.get();
7590        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7591            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7592                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7593            uid = tlsIdentity.uid;
7594            pid = tlsIdentity.pid;
7595        }
7596
7597        return checkComponentPermission(permission, pid, uid, -1, true);
7598    }
7599
7600    /**
7601     * Binder IPC calls go through the public entry point.
7602     * This can be called with or without the global lock held.
7603     */
7604    int checkCallingPermission(String permission) {
7605        return checkPermission(permission,
7606                Binder.getCallingPid(),
7607                UserHandle.getAppId(Binder.getCallingUid()));
7608    }
7609
7610    /**
7611     * This can be called with or without the global lock held.
7612     */
7613    void enforceCallingPermission(String permission, String func) {
7614        if (checkCallingPermission(permission)
7615                == PackageManager.PERMISSION_GRANTED) {
7616            return;
7617        }
7618
7619        String msg = "Permission Denial: " + func + " from pid="
7620                + Binder.getCallingPid()
7621                + ", uid=" + Binder.getCallingUid()
7622                + " requires " + permission;
7623        Slog.w(TAG, msg);
7624        throw new SecurityException(msg);
7625    }
7626
7627    /**
7628     * Determine if UID is holding permissions required to access {@link Uri} in
7629     * the given {@link ProviderInfo}. Final permission checking is always done
7630     * in {@link ContentProvider}.
7631     */
7632    private final boolean checkHoldingPermissionsLocked(
7633            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7634        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7635                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7636        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7637            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7638                    != PERMISSION_GRANTED) {
7639                return false;
7640            }
7641        }
7642        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7643    }
7644
7645    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7646            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7647        if (pi.applicationInfo.uid == uid) {
7648            return true;
7649        } else if (!pi.exported) {
7650            return false;
7651        }
7652
7653        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7654        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7655        try {
7656            // check if target holds top-level <provider> permissions
7657            if (!readMet && pi.readPermission != null && considerUidPermissions
7658                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7659                readMet = true;
7660            }
7661            if (!writeMet && pi.writePermission != null && considerUidPermissions
7662                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7663                writeMet = true;
7664            }
7665
7666            // track if unprotected read/write is allowed; any denied
7667            // <path-permission> below removes this ability
7668            boolean allowDefaultRead = pi.readPermission == null;
7669            boolean allowDefaultWrite = pi.writePermission == null;
7670
7671            // check if target holds any <path-permission> that match uri
7672            final PathPermission[] pps = pi.pathPermissions;
7673            if (pps != null) {
7674                final String path = grantUri.uri.getPath();
7675                int i = pps.length;
7676                while (i > 0 && (!readMet || !writeMet)) {
7677                    i--;
7678                    PathPermission pp = pps[i];
7679                    if (pp.match(path)) {
7680                        if (!readMet) {
7681                            final String pprperm = pp.getReadPermission();
7682                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7683                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7684                                    + ": match=" + pp.match(path)
7685                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7686                            if (pprperm != null) {
7687                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7688                                        == PERMISSION_GRANTED) {
7689                                    readMet = true;
7690                                } else {
7691                                    allowDefaultRead = false;
7692                                }
7693                            }
7694                        }
7695                        if (!writeMet) {
7696                            final String ppwperm = pp.getWritePermission();
7697                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7698                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7699                                    + ": match=" + pp.match(path)
7700                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7701                            if (ppwperm != null) {
7702                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7703                                        == PERMISSION_GRANTED) {
7704                                    writeMet = true;
7705                                } else {
7706                                    allowDefaultWrite = false;
7707                                }
7708                            }
7709                        }
7710                    }
7711                }
7712            }
7713
7714            // grant unprotected <provider> read/write, if not blocked by
7715            // <path-permission> above
7716            if (allowDefaultRead) readMet = true;
7717            if (allowDefaultWrite) writeMet = true;
7718
7719        } catch (RemoteException e) {
7720            return false;
7721        }
7722
7723        return readMet && writeMet;
7724    }
7725
7726    public int getAppStartMode(int uid, String packageName) {
7727        synchronized (this) {
7728            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7729        }
7730    }
7731
7732    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7733            boolean allowWhenForeground) {
7734        UidRecord uidRec = mActiveUids.get(uid);
7735        if (!mLenientBackgroundCheck) {
7736            if (!allowWhenForeground || uidRec == null
7737                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7738                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7739                        packageName) != AppOpsManager.MODE_ALLOWED) {
7740                    return ActivityManager.APP_START_MODE_DELAYED;
7741                }
7742            }
7743
7744        } else if (uidRec == null || uidRec.idle) {
7745            if (callingPid >= 0) {
7746                ProcessRecord proc;
7747                synchronized (mPidsSelfLocked) {
7748                    proc = mPidsSelfLocked.get(callingPid);
7749                }
7750                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7751                    // Whoever is instigating this is in the foreground, so we will allow it
7752                    // to go through.
7753                    return ActivityManager.APP_START_MODE_NORMAL;
7754                }
7755            }
7756            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7757                    != AppOpsManager.MODE_ALLOWED) {
7758                return ActivityManager.APP_START_MODE_DELAYED;
7759            }
7760        }
7761        return ActivityManager.APP_START_MODE_NORMAL;
7762    }
7763
7764    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7765        ProviderInfo pi = null;
7766        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7767        if (cpr != null) {
7768            pi = cpr.info;
7769        } else {
7770            try {
7771                pi = AppGlobals.getPackageManager().resolveContentProvider(
7772                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7773            } catch (RemoteException ex) {
7774            }
7775        }
7776        return pi;
7777    }
7778
7779    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7780        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7781        if (targetUris != null) {
7782            return targetUris.get(grantUri);
7783        }
7784        return null;
7785    }
7786
7787    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7788            String targetPkg, int targetUid, GrantUri grantUri) {
7789        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7790        if (targetUris == null) {
7791            targetUris = Maps.newArrayMap();
7792            mGrantedUriPermissions.put(targetUid, targetUris);
7793        }
7794
7795        UriPermission perm = targetUris.get(grantUri);
7796        if (perm == null) {
7797            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7798            targetUris.put(grantUri, perm);
7799        }
7800
7801        return perm;
7802    }
7803
7804    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7805            final int modeFlags) {
7806        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7807        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7808                : UriPermission.STRENGTH_OWNED;
7809
7810        // Root gets to do everything.
7811        if (uid == 0) {
7812            return true;
7813        }
7814
7815        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7816        if (perms == null) return false;
7817
7818        // First look for exact match
7819        final UriPermission exactPerm = perms.get(grantUri);
7820        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7821            return true;
7822        }
7823
7824        // No exact match, look for prefixes
7825        final int N = perms.size();
7826        for (int i = 0; i < N; i++) {
7827            final UriPermission perm = perms.valueAt(i);
7828            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7829                    && perm.getStrength(modeFlags) >= minStrength) {
7830                return true;
7831            }
7832        }
7833
7834        return false;
7835    }
7836
7837    /**
7838     * @param uri This uri must NOT contain an embedded userId.
7839     * @param userId The userId in which the uri is to be resolved.
7840     */
7841    @Override
7842    public int checkUriPermission(Uri uri, int pid, int uid,
7843            final int modeFlags, int userId, IBinder callerToken) {
7844        enforceNotIsolatedCaller("checkUriPermission");
7845
7846        // Another redirected-binder-call permissions check as in
7847        // {@link checkPermissionWithToken}.
7848        Identity tlsIdentity = sCallerIdentity.get();
7849        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7850            uid = tlsIdentity.uid;
7851            pid = tlsIdentity.pid;
7852        }
7853
7854        // Our own process gets to do everything.
7855        if (pid == MY_PID) {
7856            return PackageManager.PERMISSION_GRANTED;
7857        }
7858        synchronized (this) {
7859            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7860                    ? PackageManager.PERMISSION_GRANTED
7861                    : PackageManager.PERMISSION_DENIED;
7862        }
7863    }
7864
7865    /**
7866     * Check if the targetPkg can be granted permission to access uri by
7867     * the callingUid using the given modeFlags.  Throws a security exception
7868     * if callingUid is not allowed to do this.  Returns the uid of the target
7869     * if the URI permission grant should be performed; returns -1 if it is not
7870     * needed (for example targetPkg already has permission to access the URI).
7871     * If you already know the uid of the target, you can supply it in
7872     * lastTargetUid else set that to -1.
7873     */
7874    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7875            final int modeFlags, int lastTargetUid) {
7876        if (!Intent.isAccessUriMode(modeFlags)) {
7877            return -1;
7878        }
7879
7880        if (targetPkg != null) {
7881            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7882                    "Checking grant " + targetPkg + " permission to " + grantUri);
7883        }
7884
7885        final IPackageManager pm = AppGlobals.getPackageManager();
7886
7887        // If this is not a content: uri, we can't do anything with it.
7888        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7889            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7890                    "Can't grant URI permission for non-content URI: " + grantUri);
7891            return -1;
7892        }
7893
7894        final String authority = grantUri.uri.getAuthority();
7895        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7896        if (pi == null) {
7897            Slog.w(TAG, "No content provider found for permission check: " +
7898                    grantUri.uri.toSafeString());
7899            return -1;
7900        }
7901
7902        int targetUid = lastTargetUid;
7903        if (targetUid < 0 && targetPkg != null) {
7904            try {
7905                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7906                        UserHandle.getUserId(callingUid));
7907                if (targetUid < 0) {
7908                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7909                            "Can't grant URI permission no uid for: " + targetPkg);
7910                    return -1;
7911                }
7912            } catch (RemoteException ex) {
7913                return -1;
7914            }
7915        }
7916
7917        if (targetUid >= 0) {
7918            // First...  does the target actually need this permission?
7919            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7920                // No need to grant the target this permission.
7921                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7922                        "Target " + targetPkg + " already has full permission to " + grantUri);
7923                return -1;
7924            }
7925        } else {
7926            // First...  there is no target package, so can anyone access it?
7927            boolean allowed = pi.exported;
7928            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7929                if (pi.readPermission != null) {
7930                    allowed = false;
7931                }
7932            }
7933            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7934                if (pi.writePermission != null) {
7935                    allowed = false;
7936                }
7937            }
7938            if (allowed) {
7939                return -1;
7940            }
7941        }
7942
7943        /* There is a special cross user grant if:
7944         * - The target is on another user.
7945         * - Apps on the current user can access the uri without any uid permissions.
7946         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7947         * grant uri permissions.
7948         */
7949        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7950                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7951                modeFlags, false /*without considering the uid permissions*/);
7952
7953        // Second...  is the provider allowing granting of URI permissions?
7954        if (!specialCrossUserGrant) {
7955            if (!pi.grantUriPermissions) {
7956                throw new SecurityException("Provider " + pi.packageName
7957                        + "/" + pi.name
7958                        + " does not allow granting of Uri permissions (uri "
7959                        + grantUri + ")");
7960            }
7961            if (pi.uriPermissionPatterns != null) {
7962                final int N = pi.uriPermissionPatterns.length;
7963                boolean allowed = false;
7964                for (int i=0; i<N; i++) {
7965                    if (pi.uriPermissionPatterns[i] != null
7966                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7967                        allowed = true;
7968                        break;
7969                    }
7970                }
7971                if (!allowed) {
7972                    throw new SecurityException("Provider " + pi.packageName
7973                            + "/" + pi.name
7974                            + " does not allow granting of permission to path of Uri "
7975                            + grantUri);
7976                }
7977            }
7978        }
7979
7980        // Third...  does the caller itself have permission to access
7981        // this uri?
7982        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7983            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7984                // Require they hold a strong enough Uri permission
7985                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7986                    throw new SecurityException("Uid " + callingUid
7987                            + " does not have permission to uri " + grantUri);
7988                }
7989            }
7990        }
7991        return targetUid;
7992    }
7993
7994    /**
7995     * @param uri This uri must NOT contain an embedded userId.
7996     * @param userId The userId in which the uri is to be resolved.
7997     */
7998    @Override
7999    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8000            final int modeFlags, int userId) {
8001        enforceNotIsolatedCaller("checkGrantUriPermission");
8002        synchronized(this) {
8003            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8004                    new GrantUri(userId, uri, false), modeFlags, -1);
8005        }
8006    }
8007
8008    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8009            final int modeFlags, UriPermissionOwner owner) {
8010        if (!Intent.isAccessUriMode(modeFlags)) {
8011            return;
8012        }
8013
8014        // So here we are: the caller has the assumed permission
8015        // to the uri, and the target doesn't.  Let's now give this to
8016        // the target.
8017
8018        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8019                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8020
8021        final String authority = grantUri.uri.getAuthority();
8022        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8023        if (pi == null) {
8024            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8025            return;
8026        }
8027
8028        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8029            grantUri.prefix = true;
8030        }
8031        final UriPermission perm = findOrCreateUriPermissionLocked(
8032                pi.packageName, targetPkg, targetUid, grantUri);
8033        perm.grantModes(modeFlags, owner);
8034    }
8035
8036    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8037            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8038        if (targetPkg == null) {
8039            throw new NullPointerException("targetPkg");
8040        }
8041        int targetUid;
8042        final IPackageManager pm = AppGlobals.getPackageManager();
8043        try {
8044            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8045        } catch (RemoteException ex) {
8046            return;
8047        }
8048
8049        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8050                targetUid);
8051        if (targetUid < 0) {
8052            return;
8053        }
8054
8055        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8056                owner);
8057    }
8058
8059    static class NeededUriGrants extends ArrayList<GrantUri> {
8060        final String targetPkg;
8061        final int targetUid;
8062        final int flags;
8063
8064        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8065            this.targetPkg = targetPkg;
8066            this.targetUid = targetUid;
8067            this.flags = flags;
8068        }
8069    }
8070
8071    /**
8072     * Like checkGrantUriPermissionLocked, but takes an Intent.
8073     */
8074    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8075            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8076        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8077                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8078                + " clip=" + (intent != null ? intent.getClipData() : null)
8079                + " from " + intent + "; flags=0x"
8080                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8081
8082        if (targetPkg == null) {
8083            throw new NullPointerException("targetPkg");
8084        }
8085
8086        if (intent == null) {
8087            return null;
8088        }
8089        Uri data = intent.getData();
8090        ClipData clip = intent.getClipData();
8091        if (data == null && clip == null) {
8092            return null;
8093        }
8094        // Default userId for uris in the intent (if they don't specify it themselves)
8095        int contentUserHint = intent.getContentUserHint();
8096        if (contentUserHint == UserHandle.USER_CURRENT) {
8097            contentUserHint = UserHandle.getUserId(callingUid);
8098        }
8099        final IPackageManager pm = AppGlobals.getPackageManager();
8100        int targetUid;
8101        if (needed != null) {
8102            targetUid = needed.targetUid;
8103        } else {
8104            try {
8105                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8106                        targetUserId);
8107            } catch (RemoteException ex) {
8108                return null;
8109            }
8110            if (targetUid < 0) {
8111                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8112                        "Can't grant URI permission no uid for: " + targetPkg
8113                        + " on user " + targetUserId);
8114                return null;
8115            }
8116        }
8117        if (data != null) {
8118            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8119            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8120                    targetUid);
8121            if (targetUid > 0) {
8122                if (needed == null) {
8123                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8124                }
8125                needed.add(grantUri);
8126            }
8127        }
8128        if (clip != null) {
8129            for (int i=0; i<clip.getItemCount(); i++) {
8130                Uri uri = clip.getItemAt(i).getUri();
8131                if (uri != null) {
8132                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8133                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8134                            targetUid);
8135                    if (targetUid > 0) {
8136                        if (needed == null) {
8137                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8138                        }
8139                        needed.add(grantUri);
8140                    }
8141                } else {
8142                    Intent clipIntent = clip.getItemAt(i).getIntent();
8143                    if (clipIntent != null) {
8144                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8145                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8146                        if (newNeeded != null) {
8147                            needed = newNeeded;
8148                        }
8149                    }
8150                }
8151            }
8152        }
8153
8154        return needed;
8155    }
8156
8157    /**
8158     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8159     */
8160    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8161            UriPermissionOwner owner) {
8162        if (needed != null) {
8163            for (int i=0; i<needed.size(); i++) {
8164                GrantUri grantUri = needed.get(i);
8165                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8166                        grantUri, needed.flags, owner);
8167            }
8168        }
8169    }
8170
8171    void grantUriPermissionFromIntentLocked(int callingUid,
8172            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8173        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8174                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8175        if (needed == null) {
8176            return;
8177        }
8178
8179        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8180    }
8181
8182    /**
8183     * @param uri This uri must NOT contain an embedded userId.
8184     * @param userId The userId in which the uri is to be resolved.
8185     */
8186    @Override
8187    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8188            final int modeFlags, int userId) {
8189        enforceNotIsolatedCaller("grantUriPermission");
8190        GrantUri grantUri = new GrantUri(userId, uri, false);
8191        synchronized(this) {
8192            final ProcessRecord r = getRecordForAppLocked(caller);
8193            if (r == null) {
8194                throw new SecurityException("Unable to find app for caller "
8195                        + caller
8196                        + " when granting permission to uri " + grantUri);
8197            }
8198            if (targetPkg == null) {
8199                throw new IllegalArgumentException("null target");
8200            }
8201            if (grantUri == null) {
8202                throw new IllegalArgumentException("null uri");
8203            }
8204
8205            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8206                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8207                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8208                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8209
8210            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8211                    UserHandle.getUserId(r.uid));
8212        }
8213    }
8214
8215    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8216        if (perm.modeFlags == 0) {
8217            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8218                    perm.targetUid);
8219            if (perms != null) {
8220                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8221                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8222
8223                perms.remove(perm.uri);
8224                if (perms.isEmpty()) {
8225                    mGrantedUriPermissions.remove(perm.targetUid);
8226                }
8227            }
8228        }
8229    }
8230
8231    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8232        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8233                "Revoking all granted permissions to " + grantUri);
8234
8235        final IPackageManager pm = AppGlobals.getPackageManager();
8236        final String authority = grantUri.uri.getAuthority();
8237        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8238        if (pi == null) {
8239            Slog.w(TAG, "No content provider found for permission revoke: "
8240                    + grantUri.toSafeString());
8241            return;
8242        }
8243
8244        // Does the caller have this permission on the URI?
8245        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8246            // If they don't have direct access to the URI, then revoke any
8247            // ownerless URI permissions that have been granted to them.
8248            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8249            if (perms != null) {
8250                boolean persistChanged = false;
8251                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8252                    final UriPermission perm = it.next();
8253                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8254                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8255                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8256                                "Revoking non-owned " + perm.targetUid
8257                                + " permission to " + perm.uri);
8258                        persistChanged |= perm.revokeModes(
8259                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8260                        if (perm.modeFlags == 0) {
8261                            it.remove();
8262                        }
8263                    }
8264                }
8265                if (perms.isEmpty()) {
8266                    mGrantedUriPermissions.remove(callingUid);
8267                }
8268                if (persistChanged) {
8269                    schedulePersistUriGrants();
8270                }
8271            }
8272            return;
8273        }
8274
8275        boolean persistChanged = false;
8276
8277        // Go through all of the permissions and remove any that match.
8278        int N = mGrantedUriPermissions.size();
8279        for (int i = 0; i < N; i++) {
8280            final int targetUid = mGrantedUriPermissions.keyAt(i);
8281            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8282
8283            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8284                final UriPermission perm = it.next();
8285                if (perm.uri.sourceUserId == grantUri.sourceUserId
8286                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8287                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8288                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8289                    persistChanged |= perm.revokeModes(
8290                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8291                    if (perm.modeFlags == 0) {
8292                        it.remove();
8293                    }
8294                }
8295            }
8296
8297            if (perms.isEmpty()) {
8298                mGrantedUriPermissions.remove(targetUid);
8299                N--;
8300                i--;
8301            }
8302        }
8303
8304        if (persistChanged) {
8305            schedulePersistUriGrants();
8306        }
8307    }
8308
8309    /**
8310     * @param uri This uri must NOT contain an embedded userId.
8311     * @param userId The userId in which the uri is to be resolved.
8312     */
8313    @Override
8314    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8315            int userId) {
8316        enforceNotIsolatedCaller("revokeUriPermission");
8317        synchronized(this) {
8318            final ProcessRecord r = getRecordForAppLocked(caller);
8319            if (r == null) {
8320                throw new SecurityException("Unable to find app for caller "
8321                        + caller
8322                        + " when revoking permission to uri " + uri);
8323            }
8324            if (uri == null) {
8325                Slog.w(TAG, "revokeUriPermission: null uri");
8326                return;
8327            }
8328
8329            if (!Intent.isAccessUriMode(modeFlags)) {
8330                return;
8331            }
8332
8333            final String authority = uri.getAuthority();
8334            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8335            if (pi == null) {
8336                Slog.w(TAG, "No content provider found for permission revoke: "
8337                        + uri.toSafeString());
8338                return;
8339            }
8340
8341            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8342        }
8343    }
8344
8345    /**
8346     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8347     * given package.
8348     *
8349     * @param packageName Package name to match, or {@code null} to apply to all
8350     *            packages.
8351     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8352     *            to all users.
8353     * @param persistable If persistable grants should be removed.
8354     */
8355    private void removeUriPermissionsForPackageLocked(
8356            String packageName, int userHandle, boolean persistable) {
8357        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8358            throw new IllegalArgumentException("Must narrow by either package or user");
8359        }
8360
8361        boolean persistChanged = false;
8362
8363        int N = mGrantedUriPermissions.size();
8364        for (int i = 0; i < N; i++) {
8365            final int targetUid = mGrantedUriPermissions.keyAt(i);
8366            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8367
8368            // Only inspect grants matching user
8369            if (userHandle == UserHandle.USER_ALL
8370                    || userHandle == UserHandle.getUserId(targetUid)) {
8371                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8372                    final UriPermission perm = it.next();
8373
8374                    // Only inspect grants matching package
8375                    if (packageName == null || perm.sourcePkg.equals(packageName)
8376                            || perm.targetPkg.equals(packageName)) {
8377                        persistChanged |= perm.revokeModes(persistable
8378                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8379
8380                        // Only remove when no modes remain; any persisted grants
8381                        // will keep this alive.
8382                        if (perm.modeFlags == 0) {
8383                            it.remove();
8384                        }
8385                    }
8386                }
8387
8388                if (perms.isEmpty()) {
8389                    mGrantedUriPermissions.remove(targetUid);
8390                    N--;
8391                    i--;
8392                }
8393            }
8394        }
8395
8396        if (persistChanged) {
8397            schedulePersistUriGrants();
8398        }
8399    }
8400
8401    @Override
8402    public IBinder newUriPermissionOwner(String name) {
8403        enforceNotIsolatedCaller("newUriPermissionOwner");
8404        synchronized(this) {
8405            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8406            return owner.getExternalTokenLocked();
8407        }
8408    }
8409
8410    @Override
8411    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8412        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8413        synchronized(this) {
8414            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8415            if (r == null) {
8416                throw new IllegalArgumentException("Activity does not exist; token="
8417                        + activityToken);
8418            }
8419            return r.getUriPermissionsLocked().getExternalTokenLocked();
8420        }
8421    }
8422    /**
8423     * @param uri This uri must NOT contain an embedded userId.
8424     * @param sourceUserId The userId in which the uri is to be resolved.
8425     * @param targetUserId The userId of the app that receives the grant.
8426     */
8427    @Override
8428    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8429            final int modeFlags, int sourceUserId, int targetUserId) {
8430        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8431                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8432                "grantUriPermissionFromOwner", null);
8433        synchronized(this) {
8434            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8435            if (owner == null) {
8436                throw new IllegalArgumentException("Unknown owner: " + token);
8437            }
8438            if (fromUid != Binder.getCallingUid()) {
8439                if (Binder.getCallingUid() != Process.myUid()) {
8440                    // Only system code can grant URI permissions on behalf
8441                    // of other users.
8442                    throw new SecurityException("nice try");
8443                }
8444            }
8445            if (targetPkg == null) {
8446                throw new IllegalArgumentException("null target");
8447            }
8448            if (uri == null) {
8449                throw new IllegalArgumentException("null uri");
8450            }
8451
8452            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8453                    modeFlags, owner, targetUserId);
8454        }
8455    }
8456
8457    /**
8458     * @param uri This uri must NOT contain an embedded userId.
8459     * @param userId The userId in which the uri is to be resolved.
8460     */
8461    @Override
8462    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8463        synchronized(this) {
8464            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8465            if (owner == null) {
8466                throw new IllegalArgumentException("Unknown owner: " + token);
8467            }
8468
8469            if (uri == null) {
8470                owner.removeUriPermissionsLocked(mode);
8471            } else {
8472                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8473            }
8474        }
8475    }
8476
8477    private void schedulePersistUriGrants() {
8478        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8479            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8480                    10 * DateUtils.SECOND_IN_MILLIS);
8481        }
8482    }
8483
8484    private void writeGrantedUriPermissions() {
8485        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8486
8487        // Snapshot permissions so we can persist without lock
8488        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8489        synchronized (this) {
8490            final int size = mGrantedUriPermissions.size();
8491            for (int i = 0; i < size; i++) {
8492                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8493                for (UriPermission perm : perms.values()) {
8494                    if (perm.persistedModeFlags != 0) {
8495                        persist.add(perm.snapshot());
8496                    }
8497                }
8498            }
8499        }
8500
8501        FileOutputStream fos = null;
8502        try {
8503            fos = mGrantFile.startWrite();
8504
8505            XmlSerializer out = new FastXmlSerializer();
8506            out.setOutput(fos, StandardCharsets.UTF_8.name());
8507            out.startDocument(null, true);
8508            out.startTag(null, TAG_URI_GRANTS);
8509            for (UriPermission.Snapshot perm : persist) {
8510                out.startTag(null, TAG_URI_GRANT);
8511                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8512                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8513                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8514                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8515                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8516                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8517                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8518                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8519                out.endTag(null, TAG_URI_GRANT);
8520            }
8521            out.endTag(null, TAG_URI_GRANTS);
8522            out.endDocument();
8523
8524            mGrantFile.finishWrite(fos);
8525        } catch (IOException e) {
8526            if (fos != null) {
8527                mGrantFile.failWrite(fos);
8528            }
8529        }
8530    }
8531
8532    private void readGrantedUriPermissionsLocked() {
8533        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8534
8535        final long now = System.currentTimeMillis();
8536
8537        FileInputStream fis = null;
8538        try {
8539            fis = mGrantFile.openRead();
8540            final XmlPullParser in = Xml.newPullParser();
8541            in.setInput(fis, StandardCharsets.UTF_8.name());
8542
8543            int type;
8544            while ((type = in.next()) != END_DOCUMENT) {
8545                final String tag = in.getName();
8546                if (type == START_TAG) {
8547                    if (TAG_URI_GRANT.equals(tag)) {
8548                        final int sourceUserId;
8549                        final int targetUserId;
8550                        final int userHandle = readIntAttribute(in,
8551                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8552                        if (userHandle != UserHandle.USER_NULL) {
8553                            // For backwards compatibility.
8554                            sourceUserId = userHandle;
8555                            targetUserId = userHandle;
8556                        } else {
8557                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8558                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8559                        }
8560                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8561                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8562                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8563                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8564                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8565                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8566
8567                        // Sanity check that provider still belongs to source package
8568                        final ProviderInfo pi = getProviderInfoLocked(
8569                                uri.getAuthority(), sourceUserId);
8570                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8571                            int targetUid = -1;
8572                            try {
8573                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8574                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8575                            } catch (RemoteException e) {
8576                            }
8577                            if (targetUid != -1) {
8578                                final UriPermission perm = findOrCreateUriPermissionLocked(
8579                                        sourcePkg, targetPkg, targetUid,
8580                                        new GrantUri(sourceUserId, uri, prefix));
8581                                perm.initPersistedModes(modeFlags, createdTime);
8582                            }
8583                        } else {
8584                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8585                                    + " but instead found " + pi);
8586                        }
8587                    }
8588                }
8589            }
8590        } catch (FileNotFoundException e) {
8591            // Missing grants is okay
8592        } catch (IOException e) {
8593            Slog.wtf(TAG, "Failed reading Uri grants", e);
8594        } catch (XmlPullParserException e) {
8595            Slog.wtf(TAG, "Failed reading Uri grants", e);
8596        } finally {
8597            IoUtils.closeQuietly(fis);
8598        }
8599    }
8600
8601    /**
8602     * @param uri This uri must NOT contain an embedded userId.
8603     * @param userId The userId in which the uri is to be resolved.
8604     */
8605    @Override
8606    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8607        enforceNotIsolatedCaller("takePersistableUriPermission");
8608
8609        Preconditions.checkFlagsArgument(modeFlags,
8610                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8611
8612        synchronized (this) {
8613            final int callingUid = Binder.getCallingUid();
8614            boolean persistChanged = false;
8615            GrantUri grantUri = new GrantUri(userId, uri, false);
8616
8617            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8618                    new GrantUri(userId, uri, false));
8619            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8620                    new GrantUri(userId, uri, true));
8621
8622            final boolean exactValid = (exactPerm != null)
8623                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8624            final boolean prefixValid = (prefixPerm != null)
8625                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8626
8627            if (!(exactValid || prefixValid)) {
8628                throw new SecurityException("No persistable permission grants found for UID "
8629                        + callingUid + " and Uri " + grantUri.toSafeString());
8630            }
8631
8632            if (exactValid) {
8633                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8634            }
8635            if (prefixValid) {
8636                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8637            }
8638
8639            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8640
8641            if (persistChanged) {
8642                schedulePersistUriGrants();
8643            }
8644        }
8645    }
8646
8647    /**
8648     * @param uri This uri must NOT contain an embedded userId.
8649     * @param userId The userId in which the uri is to be resolved.
8650     */
8651    @Override
8652    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8653        enforceNotIsolatedCaller("releasePersistableUriPermission");
8654
8655        Preconditions.checkFlagsArgument(modeFlags,
8656                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8657
8658        synchronized (this) {
8659            final int callingUid = Binder.getCallingUid();
8660            boolean persistChanged = false;
8661
8662            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8663                    new GrantUri(userId, uri, false));
8664            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8665                    new GrantUri(userId, uri, true));
8666            if (exactPerm == null && prefixPerm == null) {
8667                throw new SecurityException("No permission grants found for UID " + callingUid
8668                        + " and Uri " + uri.toSafeString());
8669            }
8670
8671            if (exactPerm != null) {
8672                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8673                removeUriPermissionIfNeededLocked(exactPerm);
8674            }
8675            if (prefixPerm != null) {
8676                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8677                removeUriPermissionIfNeededLocked(prefixPerm);
8678            }
8679
8680            if (persistChanged) {
8681                schedulePersistUriGrants();
8682            }
8683        }
8684    }
8685
8686    /**
8687     * Prune any older {@link UriPermission} for the given UID until outstanding
8688     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8689     *
8690     * @return if any mutations occured that require persisting.
8691     */
8692    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8693        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8694        if (perms == null) return false;
8695        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8696
8697        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8698        for (UriPermission perm : perms.values()) {
8699            if (perm.persistedModeFlags != 0) {
8700                persisted.add(perm);
8701            }
8702        }
8703
8704        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8705        if (trimCount <= 0) return false;
8706
8707        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8708        for (int i = 0; i < trimCount; i++) {
8709            final UriPermission perm = persisted.get(i);
8710
8711            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8712                    "Trimming grant created at " + perm.persistedCreateTime);
8713
8714            perm.releasePersistableModes(~0);
8715            removeUriPermissionIfNeededLocked(perm);
8716        }
8717
8718        return true;
8719    }
8720
8721    @Override
8722    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8723            String packageName, boolean incoming) {
8724        enforceNotIsolatedCaller("getPersistedUriPermissions");
8725        Preconditions.checkNotNull(packageName, "packageName");
8726
8727        final int callingUid = Binder.getCallingUid();
8728        final IPackageManager pm = AppGlobals.getPackageManager();
8729        try {
8730            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8731                    UserHandle.getUserId(callingUid));
8732            if (packageUid != callingUid) {
8733                throw new SecurityException(
8734                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8735            }
8736        } catch (RemoteException e) {
8737            throw new SecurityException("Failed to verify package name ownership");
8738        }
8739
8740        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8741        synchronized (this) {
8742            if (incoming) {
8743                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8744                        callingUid);
8745                if (perms == null) {
8746                    Slog.w(TAG, "No permission grants found for " + packageName);
8747                } else {
8748                    for (UriPermission perm : perms.values()) {
8749                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8750                            result.add(perm.buildPersistedPublicApiObject());
8751                        }
8752                    }
8753                }
8754            } else {
8755                final int size = mGrantedUriPermissions.size();
8756                for (int i = 0; i < size; i++) {
8757                    final ArrayMap<GrantUri, UriPermission> perms =
8758                            mGrantedUriPermissions.valueAt(i);
8759                    for (UriPermission perm : perms.values()) {
8760                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8761                            result.add(perm.buildPersistedPublicApiObject());
8762                        }
8763                    }
8764                }
8765            }
8766        }
8767        return new ParceledListSlice<android.content.UriPermission>(result);
8768    }
8769
8770    @Override
8771    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8772            String packageName, int userId) {
8773        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8774                "getGrantedUriPermissions");
8775
8776        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8777        synchronized (this) {
8778            final int size = mGrantedUriPermissions.size();
8779            for (int i = 0; i < size; i++) {
8780                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8781                for (UriPermission perm : perms.values()) {
8782                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8783                            && perm.persistedModeFlags != 0) {
8784                        result.add(perm.buildPersistedPublicApiObject());
8785                    }
8786                }
8787            }
8788        }
8789        return new ParceledListSlice<android.content.UriPermission>(result);
8790    }
8791
8792    @Override
8793    public void clearGrantedUriPermissions(String packageName, int userId) {
8794        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8795                "clearGrantedUriPermissions");
8796        removeUriPermissionsForPackageLocked(packageName, userId, true);
8797    }
8798
8799    @Override
8800    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8801        synchronized (this) {
8802            ProcessRecord app =
8803                who != null ? getRecordForAppLocked(who) : null;
8804            if (app == null) return;
8805
8806            Message msg = Message.obtain();
8807            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8808            msg.obj = app;
8809            msg.arg1 = waiting ? 1 : 0;
8810            mUiHandler.sendMessage(msg);
8811        }
8812    }
8813
8814    @Override
8815    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8816        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8817        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8818        outInfo.availMem = Process.getFreeMemory();
8819        outInfo.totalMem = Process.getTotalMemory();
8820        outInfo.threshold = homeAppMem;
8821        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8822        outInfo.hiddenAppThreshold = cachedAppMem;
8823        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8824                ProcessList.SERVICE_ADJ);
8825        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8826                ProcessList.VISIBLE_APP_ADJ);
8827        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8828                ProcessList.FOREGROUND_APP_ADJ);
8829    }
8830
8831    // =========================================================
8832    // TASK MANAGEMENT
8833    // =========================================================
8834
8835    @Override
8836    public List<IAppTask> getAppTasks(String callingPackage) {
8837        int callingUid = Binder.getCallingUid();
8838        long ident = Binder.clearCallingIdentity();
8839
8840        synchronized(this) {
8841            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8842            try {
8843                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8844
8845                final int N = mRecentTasks.size();
8846                for (int i = 0; i < N; i++) {
8847                    TaskRecord tr = mRecentTasks.get(i);
8848                    // Skip tasks that do not match the caller.  We don't need to verify
8849                    // callingPackage, because we are also limiting to callingUid and know
8850                    // that will limit to the correct security sandbox.
8851                    if (tr.effectiveUid != callingUid) {
8852                        continue;
8853                    }
8854                    Intent intent = tr.getBaseIntent();
8855                    if (intent == null ||
8856                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8857                        continue;
8858                    }
8859                    ActivityManager.RecentTaskInfo taskInfo =
8860                            createRecentTaskInfoFromTaskRecord(tr);
8861                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8862                    list.add(taskImpl);
8863                }
8864            } finally {
8865                Binder.restoreCallingIdentity(ident);
8866            }
8867            return list;
8868        }
8869    }
8870
8871    @Override
8872    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8873        final int callingUid = Binder.getCallingUid();
8874        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8875
8876        synchronized(this) {
8877            if (DEBUG_ALL) Slog.v(
8878                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8879
8880            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8881                    callingUid);
8882
8883            // TODO: Improve with MRU list from all ActivityStacks.
8884            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8885        }
8886
8887        return list;
8888    }
8889
8890    /**
8891     * Creates a new RecentTaskInfo from a TaskRecord.
8892     */
8893    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8894        // Update the task description to reflect any changes in the task stack
8895        tr.updateTaskDescription();
8896
8897        // Compose the recent task info
8898        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8899        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8900        rti.persistentId = tr.taskId;
8901        rti.baseIntent = new Intent(tr.getBaseIntent());
8902        rti.origActivity = tr.origActivity;
8903        rti.realActivity = tr.realActivity;
8904        rti.description = tr.lastDescription;
8905        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8906        rti.userId = tr.userId;
8907        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8908        rti.firstActiveTime = tr.firstActiveTime;
8909        rti.lastActiveTime = tr.lastActiveTime;
8910        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8911        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8912        rti.numActivities = 0;
8913        if (tr.mBounds != null) {
8914            rti.bounds = new Rect(tr.mBounds);
8915        }
8916        rti.isDockable = tr.canGoInDockedStack();
8917        rti.resizeMode = tr.mResizeMode;
8918
8919        ActivityRecord base = null;
8920        ActivityRecord top = null;
8921        ActivityRecord tmp;
8922
8923        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8924            tmp = tr.mActivities.get(i);
8925            if (tmp.finishing) {
8926                continue;
8927            }
8928            base = tmp;
8929            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8930                top = base;
8931            }
8932            rti.numActivities++;
8933        }
8934
8935        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8936        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8937
8938        return rti;
8939    }
8940
8941    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8942        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8943                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8944        if (!allowed) {
8945            if (checkPermission(android.Manifest.permission.GET_TASKS,
8946                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8947                // Temporary compatibility: some existing apps on the system image may
8948                // still be requesting the old permission and not switched to the new
8949                // one; if so, we'll still allow them full access.  This means we need
8950                // to see if they are holding the old permission and are a system app.
8951                try {
8952                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8953                        allowed = true;
8954                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8955                                + " is using old GET_TASKS but privileged; allowing");
8956                    }
8957                } catch (RemoteException e) {
8958                }
8959            }
8960        }
8961        if (!allowed) {
8962            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8963                    + " does not hold REAL_GET_TASKS; limiting output");
8964        }
8965        return allowed;
8966    }
8967
8968    @Override
8969    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8970        final int callingUid = Binder.getCallingUid();
8971        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8972                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8973
8974        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8975        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8976        synchronized (this) {
8977            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8978                    callingUid);
8979            final boolean detailed = checkCallingPermission(
8980                    android.Manifest.permission.GET_DETAILED_TASKS)
8981                    == PackageManager.PERMISSION_GRANTED;
8982
8983            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8984                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8985                return Collections.emptyList();
8986            }
8987            mRecentTasks.loadUserRecentsLocked(userId);
8988
8989            final int recentsCount = mRecentTasks.size();
8990            ArrayList<ActivityManager.RecentTaskInfo> res =
8991                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8992
8993            final Set<Integer> includedUsers;
8994            if (includeProfiles) {
8995                includedUsers = mUserController.getProfileIds(userId);
8996            } else {
8997                includedUsers = new HashSet<>();
8998            }
8999            includedUsers.add(Integer.valueOf(userId));
9000
9001            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9002                TaskRecord tr = mRecentTasks.get(i);
9003                // Only add calling user or related users recent tasks
9004                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9005                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9006                    continue;
9007                }
9008
9009                if (tr.realActivitySuspended) {
9010                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9011                    continue;
9012                }
9013
9014                // Return the entry if desired by the caller.  We always return
9015                // the first entry, because callers always expect this to be the
9016                // foreground app.  We may filter others if the caller has
9017                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9018                // we should exclude the entry.
9019
9020                if (i == 0
9021                        || withExcluded
9022                        || (tr.intent == null)
9023                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9024                                == 0)) {
9025                    if (!allowed) {
9026                        // If the caller doesn't have the GET_TASKS permission, then only
9027                        // allow them to see a small subset of tasks -- their own and home.
9028                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9029                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9030                            continue;
9031                        }
9032                    }
9033                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9034                        if (tr.stack != null && tr.stack.isHomeStack()) {
9035                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9036                                    "Skipping, home stack task: " + tr);
9037                            continue;
9038                        }
9039                    }
9040                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9041                        final ActivityStack stack = tr.stack;
9042                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9043                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9044                                    "Skipping, top task in docked stack: " + tr);
9045                            continue;
9046                        }
9047                    }
9048                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9049                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9050                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9051                                    "Skipping, pinned stack task: " + tr);
9052                            continue;
9053                        }
9054                    }
9055                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9056                        // Don't include auto remove tasks that are finished or finishing.
9057                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9058                                "Skipping, auto-remove without activity: " + tr);
9059                        continue;
9060                    }
9061                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9062                            && !tr.isAvailable) {
9063                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9064                                "Skipping, unavail real act: " + tr);
9065                        continue;
9066                    }
9067
9068                    if (!tr.mUserSetupComplete) {
9069                        // Don't include task launched while user is not done setting-up.
9070                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9071                                "Skipping, user setup not complete: " + tr);
9072                        continue;
9073                    }
9074
9075                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9076                    if (!detailed) {
9077                        rti.baseIntent.replaceExtras((Bundle)null);
9078                    }
9079
9080                    res.add(rti);
9081                    maxNum--;
9082                }
9083            }
9084            return res;
9085        }
9086    }
9087
9088    @Override
9089    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9090        synchronized (this) {
9091            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9092                    "getTaskThumbnail()");
9093            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9094                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9095            if (tr != null) {
9096                return tr.getTaskThumbnailLocked();
9097            }
9098        }
9099        return null;
9100    }
9101
9102    @Override
9103    public int addAppTask(IBinder activityToken, Intent intent,
9104            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9105        final int callingUid = Binder.getCallingUid();
9106        final long callingIdent = Binder.clearCallingIdentity();
9107
9108        try {
9109            synchronized (this) {
9110                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9111                if (r == null) {
9112                    throw new IllegalArgumentException("Activity does not exist; token="
9113                            + activityToken);
9114                }
9115                ComponentName comp = intent.getComponent();
9116                if (comp == null) {
9117                    throw new IllegalArgumentException("Intent " + intent
9118                            + " must specify explicit component");
9119                }
9120                if (thumbnail.getWidth() != mThumbnailWidth
9121                        || thumbnail.getHeight() != mThumbnailHeight) {
9122                    throw new IllegalArgumentException("Bad thumbnail size: got "
9123                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9124                            + mThumbnailWidth + "x" + mThumbnailHeight);
9125                }
9126                if (intent.getSelector() != null) {
9127                    intent.setSelector(null);
9128                }
9129                if (intent.getSourceBounds() != null) {
9130                    intent.setSourceBounds(null);
9131                }
9132                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9133                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9134                        // The caller has added this as an auto-remove task...  that makes no
9135                        // sense, so turn off auto-remove.
9136                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9137                    }
9138                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9139                    // Must be a new task.
9140                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9141                }
9142                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9143                    mLastAddedTaskActivity = null;
9144                }
9145                ActivityInfo ainfo = mLastAddedTaskActivity;
9146                if (ainfo == null) {
9147                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9148                            comp, 0, UserHandle.getUserId(callingUid));
9149                    if (ainfo.applicationInfo.uid != callingUid) {
9150                        throw new SecurityException(
9151                                "Can't add task for another application: target uid="
9152                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9153                    }
9154                }
9155
9156                // Use the full screen as the context for the task thumbnail
9157                final Point displaySize = new Point();
9158                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9159                r.task.stack.getDisplaySize(displaySize);
9160                thumbnailInfo.taskWidth = displaySize.x;
9161                thumbnailInfo.taskHeight = displaySize.y;
9162                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9163
9164                TaskRecord task = new TaskRecord(this,
9165                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9166                        ainfo, intent, description, thumbnailInfo);
9167
9168                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9169                if (trimIdx >= 0) {
9170                    // If this would have caused a trim, then we'll abort because that
9171                    // means it would be added at the end of the list but then just removed.
9172                    return INVALID_TASK_ID;
9173                }
9174
9175                final int N = mRecentTasks.size();
9176                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9177                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9178                    tr.removedFromRecents();
9179                }
9180
9181                task.inRecents = true;
9182                mRecentTasks.add(task);
9183                r.task.stack.addTask(task, false, "addAppTask");
9184
9185                task.setLastThumbnailLocked(thumbnail);
9186                task.freeLastThumbnail();
9187
9188                return task.taskId;
9189            }
9190        } finally {
9191            Binder.restoreCallingIdentity(callingIdent);
9192        }
9193    }
9194
9195    @Override
9196    public Point getAppTaskThumbnailSize() {
9197        synchronized (this) {
9198            return new Point(mThumbnailWidth,  mThumbnailHeight);
9199        }
9200    }
9201
9202    @Override
9203    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9204        synchronized (this) {
9205            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9206            if (r != null) {
9207                r.setTaskDescription(td);
9208                r.task.updateTaskDescription();
9209            }
9210        }
9211    }
9212
9213    @Override
9214    public void setTaskResizeable(int taskId, int resizeableMode) {
9215        synchronized (this) {
9216            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9217                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9218            if (task == null) {
9219                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9220                return;
9221            }
9222            if (task.mResizeMode != resizeableMode) {
9223                task.mResizeMode = resizeableMode;
9224                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9225                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9226                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9227            }
9228        }
9229    }
9230
9231    @Override
9232    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9233        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9234        long ident = Binder.clearCallingIdentity();
9235        try {
9236            synchronized (this) {
9237                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9238                if (task == null) {
9239                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9240                    return;
9241                }
9242                int stackId = task.stack.mStackId;
9243                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9244                // in crop windows resize mode or if the task size is affected by the docked stack
9245                // changing size. No need to update configuration.
9246                if (bounds != null && task.inCropWindowsResizeMode()
9247                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9248                    mWindowManager.scrollTask(task.taskId, bounds);
9249                    return;
9250                }
9251
9252                // Place the task in the right stack if it isn't there already based on
9253                // the requested bounds.
9254                // The stack transition logic is:
9255                // - a null bounds on a freeform task moves that task to fullscreen
9256                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9257                //   that task to freeform
9258                // - otherwise the task is not moved
9259                if (!StackId.isTaskResizeAllowed(stackId)) {
9260                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9261                }
9262                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9263                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9264                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9265                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9266                }
9267                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9268                if (stackId != task.stack.mStackId) {
9269                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9270                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9271                    preserveWindow = false;
9272                }
9273
9274                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9275                        false /* deferResume */);
9276            }
9277        } finally {
9278            Binder.restoreCallingIdentity(ident);
9279        }
9280    }
9281
9282    @Override
9283    public Rect getTaskBounds(int taskId) {
9284        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9285        long ident = Binder.clearCallingIdentity();
9286        Rect rect = new Rect();
9287        try {
9288            synchronized (this) {
9289                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9290                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9291                if (task == null) {
9292                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9293                    return rect;
9294                }
9295                if (task.stack != null) {
9296                    // Return the bounds from window manager since it will be adjusted for various
9297                    // things like the presense of a docked stack for tasks that aren't resizeable.
9298                    mWindowManager.getTaskBounds(task.taskId, rect);
9299                } else {
9300                    // Task isn't in window manager yet since it isn't associated with a stack.
9301                    // Return the persist value from activity manager
9302                    if (task.mBounds != null) {
9303                        rect.set(task.mBounds);
9304                    } else if (task.mLastNonFullscreenBounds != null) {
9305                        rect.set(task.mLastNonFullscreenBounds);
9306                    }
9307                }
9308            }
9309        } finally {
9310            Binder.restoreCallingIdentity(ident);
9311        }
9312        return rect;
9313    }
9314
9315    @Override
9316    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9317        if (userId != UserHandle.getCallingUserId()) {
9318            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9319                    "getTaskDescriptionIcon");
9320        }
9321        final File passedIconFile = new File(filePath);
9322        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9323                passedIconFile.getName());
9324        if (!legitIconFile.getPath().equals(filePath)
9325                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9326            throw new IllegalArgumentException("Bad file path: " + filePath
9327                    + " passed for userId " + userId);
9328        }
9329        return mRecentTasks.getTaskDescriptionIcon(filePath);
9330    }
9331
9332    @Override
9333    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9334            throws RemoteException {
9335        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9336                opts.getCustomInPlaceResId() == 0) {
9337            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9338                    "with valid animation");
9339        }
9340        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9341        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9342                opts.getCustomInPlaceResId());
9343        mWindowManager.executeAppTransition();
9344    }
9345
9346    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9347            boolean removeFromRecents) {
9348        if (removeFromRecents) {
9349            mRecentTasks.remove(tr);
9350            tr.removedFromRecents();
9351        }
9352        ComponentName component = tr.getBaseIntent().getComponent();
9353        if (component == null) {
9354            Slog.w(TAG, "No component for base intent of task: " + tr);
9355            return;
9356        }
9357
9358        // Find any running services associated with this app and stop if needed.
9359        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9360
9361        if (!killProcess) {
9362            return;
9363        }
9364
9365        // Determine if the process(es) for this task should be killed.
9366        final String pkg = component.getPackageName();
9367        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9368        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9369        for (int i = 0; i < pmap.size(); i++) {
9370
9371            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9372            for (int j = 0; j < uids.size(); j++) {
9373                ProcessRecord proc = uids.valueAt(j);
9374                if (proc.userId != tr.userId) {
9375                    // Don't kill process for a different user.
9376                    continue;
9377                }
9378                if (proc == mHomeProcess) {
9379                    // Don't kill the home process along with tasks from the same package.
9380                    continue;
9381                }
9382                if (!proc.pkgList.containsKey(pkg)) {
9383                    // Don't kill process that is not associated with this task.
9384                    continue;
9385                }
9386
9387                for (int k = 0; k < proc.activities.size(); k++) {
9388                    TaskRecord otherTask = proc.activities.get(k).task;
9389                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9390                        // Don't kill process(es) that has an activity in a different task that is
9391                        // also in recents.
9392                        return;
9393                    }
9394                }
9395
9396                if (proc.foregroundServices) {
9397                    // Don't kill process(es) with foreground service.
9398                    return;
9399                }
9400
9401                // Add process to kill list.
9402                procsToKill.add(proc);
9403            }
9404        }
9405
9406        // Kill the running processes.
9407        for (int i = 0; i < procsToKill.size(); i++) {
9408            ProcessRecord pr = procsToKill.get(i);
9409            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9410                    && pr.curReceiver == null) {
9411                pr.kill("remove task", true);
9412            } else {
9413                // We delay killing processes that are not in the background or running a receiver.
9414                pr.waitingToKill = "remove task";
9415            }
9416        }
9417    }
9418
9419    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9420        // Remove all tasks with activities in the specified package from the list of recent tasks
9421        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9422            TaskRecord tr = mRecentTasks.get(i);
9423            if (tr.userId != userId) continue;
9424
9425            ComponentName cn = tr.intent.getComponent();
9426            if (cn != null && cn.getPackageName().equals(packageName)) {
9427                // If the package name matches, remove the task.
9428                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9429            }
9430        }
9431    }
9432
9433    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9434            int userId) {
9435
9436        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9437            TaskRecord tr = mRecentTasks.get(i);
9438            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9439                continue;
9440            }
9441
9442            ComponentName cn = tr.intent.getComponent();
9443            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9444                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9445            if (sameComponent) {
9446                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9447            }
9448        }
9449    }
9450
9451    /**
9452     * Removes the task with the specified task id.
9453     *
9454     * @param taskId Identifier of the task to be removed.
9455     * @param killProcess Kill any process associated with the task if possible.
9456     * @param removeFromRecents Whether to also remove the task from recents.
9457     * @return Returns true if the given task was found and removed.
9458     */
9459    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9460            boolean removeFromRecents) {
9461        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9462                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9463        if (tr != null) {
9464            tr.removeTaskActivitiesLocked();
9465            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9466            if (tr.isPersistable) {
9467                notifyTaskPersisterLocked(null, true);
9468            }
9469            return true;
9470        }
9471        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9472        return false;
9473    }
9474
9475    @Override
9476    public void removeStack(int stackId) {
9477        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9478        if (stackId == HOME_STACK_ID) {
9479            throw new IllegalArgumentException("Removing home stack is not allowed.");
9480        }
9481
9482        synchronized (this) {
9483            final long ident = Binder.clearCallingIdentity();
9484            try {
9485                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9486                if (stack == null) {
9487                    return;
9488                }
9489                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9490                for (int i = tasks.size() - 1; i >= 0; i--) {
9491                    removeTaskByIdLocked(
9492                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9493                }
9494            } finally {
9495                Binder.restoreCallingIdentity(ident);
9496            }
9497        }
9498    }
9499
9500    @Override
9501    public boolean removeTask(int taskId) {
9502        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9503        synchronized (this) {
9504            final long ident = Binder.clearCallingIdentity();
9505            try {
9506                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9507            } finally {
9508                Binder.restoreCallingIdentity(ident);
9509            }
9510        }
9511    }
9512
9513    /**
9514     * TODO: Add mController hook
9515     */
9516    @Override
9517    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9518        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9519
9520        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9521        synchronized(this) {
9522            moveTaskToFrontLocked(taskId, flags, bOptions);
9523        }
9524    }
9525
9526    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9527        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9528
9529        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9530                Binder.getCallingUid(), -1, -1, "Task to front")) {
9531            ActivityOptions.abort(options);
9532            return;
9533        }
9534        final long origId = Binder.clearCallingIdentity();
9535        try {
9536            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9537            if (task == null) {
9538                Slog.d(TAG, "Could not find task for id: "+ taskId);
9539                return;
9540            }
9541            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9542                mStackSupervisor.showLockTaskToast();
9543                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9544                return;
9545            }
9546            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9547            if (prev != null && prev.isRecentsActivity()) {
9548                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9549            }
9550            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9551                    false /* forceNonResizable */);
9552        } finally {
9553            Binder.restoreCallingIdentity(origId);
9554        }
9555        ActivityOptions.abort(options);
9556    }
9557
9558    /**
9559     * Moves an activity, and all of the other activities within the same task, to the bottom
9560     * of the history stack.  The activity's order within the task is unchanged.
9561     *
9562     * @param token A reference to the activity we wish to move
9563     * @param nonRoot If false then this only works if the activity is the root
9564     *                of a task; if true it will work for any activity in a task.
9565     * @return Returns true if the move completed, false if not.
9566     */
9567    @Override
9568    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9569        enforceNotIsolatedCaller("moveActivityTaskToBack");
9570        synchronized(this) {
9571            final long origId = Binder.clearCallingIdentity();
9572            try {
9573                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9574                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9575                if (task != null) {
9576                    if (mStackSupervisor.isLockedTask(task)) {
9577                        mStackSupervisor.showLockTaskToast();
9578                        return false;
9579                    }
9580                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9581                }
9582            } finally {
9583                Binder.restoreCallingIdentity(origId);
9584            }
9585        }
9586        return false;
9587    }
9588
9589    @Override
9590    public void moveTaskBackwards(int task) {
9591        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9592                "moveTaskBackwards()");
9593
9594        synchronized(this) {
9595            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9596                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9597                return;
9598            }
9599            final long origId = Binder.clearCallingIdentity();
9600            moveTaskBackwardsLocked(task);
9601            Binder.restoreCallingIdentity(origId);
9602        }
9603    }
9604
9605    private final void moveTaskBackwardsLocked(int task) {
9606        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9607    }
9608
9609    @Override
9610    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9611            IActivityContainerCallback callback) throws RemoteException {
9612        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9613        synchronized (this) {
9614            if (parentActivityToken == null) {
9615                throw new IllegalArgumentException("parent token must not be null");
9616            }
9617            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9618            if (r == null) {
9619                return null;
9620            }
9621            if (callback == null) {
9622                throw new IllegalArgumentException("callback must not be null");
9623            }
9624            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9625        }
9626    }
9627
9628    @Override
9629    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9630        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9631        synchronized (this) {
9632            mStackSupervisor.deleteActivityContainer(container);
9633        }
9634    }
9635
9636    @Override
9637    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9638        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9639        synchronized (this) {
9640            final int stackId = mStackSupervisor.getNextStackId();
9641            final ActivityStack stack =
9642                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9643            if (stack == null) {
9644                return null;
9645            }
9646            return stack.mActivityContainer;
9647        }
9648    }
9649
9650    @Override
9651    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9652        synchronized (this) {
9653            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9654            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9655                return stack.mActivityContainer.getDisplayId();
9656            }
9657            return Display.DEFAULT_DISPLAY;
9658        }
9659    }
9660
9661    @Override
9662    public int getActivityStackId(IBinder token) throws RemoteException {
9663        synchronized (this) {
9664            ActivityStack stack = ActivityRecord.getStackLocked(token);
9665            if (stack == null) {
9666                return INVALID_STACK_ID;
9667            }
9668            return stack.mStackId;
9669        }
9670    }
9671
9672    @Override
9673    public void exitFreeformMode(IBinder token) throws RemoteException {
9674        synchronized (this) {
9675            long ident = Binder.clearCallingIdentity();
9676            try {
9677                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9678                if (r == null) {
9679                    throw new IllegalArgumentException(
9680                            "exitFreeformMode: No activity record matching token=" + token);
9681                }
9682                final ActivityStack stack = r.getStackLocked(token);
9683                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9684                    throw new IllegalStateException(
9685                            "exitFreeformMode: You can only go fullscreen from freeform.");
9686                }
9687                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9688                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9689                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694    }
9695
9696    @Override
9697    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9698        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9699        if (stackId == HOME_STACK_ID) {
9700            throw new IllegalArgumentException(
9701                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9702        }
9703        synchronized (this) {
9704            long ident = Binder.clearCallingIdentity();
9705            try {
9706                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9707                        + " to stackId=" + stackId + " toTop=" + toTop);
9708                if (stackId == DOCKED_STACK_ID) {
9709                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9710                            null /* initialBounds */);
9711                }
9712                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9713                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9714                if (result && stackId == DOCKED_STACK_ID) {
9715                    // If task moved to docked stack - show recents if needed.
9716                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9717                            "moveTaskToDockedStack");
9718                }
9719            } finally {
9720                Binder.restoreCallingIdentity(ident);
9721            }
9722        }
9723    }
9724
9725    @Override
9726    public void swapDockedAndFullscreenStack() throws RemoteException {
9727        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9728        synchronized (this) {
9729            long ident = Binder.clearCallingIdentity();
9730            try {
9731                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9732                        FULLSCREEN_WORKSPACE_STACK_ID);
9733                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9734                        : null;
9735                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9736                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9737                        : null;
9738                if (topTask == null || tasks == null || tasks.size() == 0) {
9739                    Slog.w(TAG,
9740                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9741                    return;
9742                }
9743
9744                // TODO: App transition
9745                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9746
9747                // Defer the resume so resume/pausing while moving stacks is dangerous.
9748                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9749                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9750                        ANIMATE, true /* deferResume */);
9751                final int size = tasks.size();
9752                for (int i = 0; i < size; i++) {
9753                    final int id = tasks.get(i).taskId;
9754                    if (id == topTask.taskId) {
9755                        continue;
9756                    }
9757                    mStackSupervisor.moveTaskToStackLocked(id,
9758                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9759                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9760                }
9761
9762                // Because we deferred the resume, to avoid conflicts with stack switches while
9763                // resuming, we need to do it after all the tasks are moved.
9764                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9765                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9766
9767                mWindowManager.executeAppTransition();
9768            } finally {
9769                Binder.restoreCallingIdentity(ident);
9770            }
9771        }
9772    }
9773
9774    /**
9775     * Moves the input task to the docked stack.
9776     *
9777     * @param taskId Id of task to move.
9778     * @param createMode The mode the docked stack should be created in if it doesn't exist
9779     *                   already. See
9780     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9781     *                   and
9782     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9783     * @param toTop If the task and stack should be moved to the top.
9784     * @param animate Whether we should play an animation for the moving the task
9785     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9786     *                      docked stack. Pass {@code null} to use default bounds.
9787     */
9788    @Override
9789    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9790            Rect initialBounds, boolean moveHomeStackFront) {
9791        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9792        synchronized (this) {
9793            long ident = Binder.clearCallingIdentity();
9794            try {
9795                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9796                        + " to createMode=" + createMode + " toTop=" + toTop);
9797                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9798                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9799                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9800                        animate, DEFER_RESUME);
9801                if (moved) {
9802                    if (moveHomeStackFront) {
9803                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9804                    }
9805                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9806                }
9807                return moved;
9808            } finally {
9809                Binder.restoreCallingIdentity(ident);
9810            }
9811        }
9812    }
9813
9814    /**
9815     * Moves the top activity in the input stackId to the pinned stack.
9816     *
9817     * @param stackId Id of stack to move the top activity to pinned stack.
9818     * @param bounds Bounds to use for pinned stack.
9819     *
9820     * @return True if the top activity of the input stack was successfully moved to the pinned
9821     *          stack.
9822     */
9823    @Override
9824    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9825        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9826        synchronized (this) {
9827            if (!mSupportsPictureInPicture) {
9828                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9829                        + "Device doesn't support picture-in-pciture mode");
9830            }
9831
9832            long ident = Binder.clearCallingIdentity();
9833            try {
9834                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9835            } finally {
9836                Binder.restoreCallingIdentity(ident);
9837            }
9838        }
9839    }
9840
9841    @Override
9842    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9843            boolean preserveWindows, boolean animate, int animationDuration) {
9844        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9845        long ident = Binder.clearCallingIdentity();
9846        try {
9847            synchronized (this) {
9848                if (animate) {
9849                    if (stackId == PINNED_STACK_ID) {
9850                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9851                    } else {
9852                        throw new IllegalArgumentException("Stack: " + stackId
9853                                + " doesn't support animated resize.");
9854                    }
9855                } else {
9856                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9857                            null /* tempTaskInsetBounds */, preserveWindows,
9858                            allowResizeInDockedMode, !DEFER_RESUME);
9859                }
9860            }
9861        } finally {
9862            Binder.restoreCallingIdentity(ident);
9863        }
9864    }
9865
9866    @Override
9867    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9868            Rect tempDockedTaskInsetBounds,
9869            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9870        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9871                "resizeDockedStack()");
9872        long ident = Binder.clearCallingIdentity();
9873        try {
9874            synchronized (this) {
9875                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9876                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9877                        PRESERVE_WINDOWS);
9878            }
9879        } finally {
9880            Binder.restoreCallingIdentity(ident);
9881        }
9882    }
9883
9884    @Override
9885    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9886        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9887                "resizePinnedStack()");
9888        final long ident = Binder.clearCallingIdentity();
9889        try {
9890            synchronized (this) {
9891                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9892            }
9893        } finally {
9894            Binder.restoreCallingIdentity(ident);
9895        }
9896    }
9897
9898    @Override
9899    public void positionTaskInStack(int taskId, int stackId, int position) {
9900        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9901        if (stackId == HOME_STACK_ID) {
9902            throw new IllegalArgumentException(
9903                    "positionTaskInStack: Attempt to change the position of task "
9904                    + taskId + " in/to home stack");
9905        }
9906        synchronized (this) {
9907            long ident = Binder.clearCallingIdentity();
9908            try {
9909                if (DEBUG_STACK) Slog.d(TAG_STACK,
9910                        "positionTaskInStack: positioning task=" + taskId
9911                        + " in stackId=" + stackId + " at position=" + position);
9912                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9913            } finally {
9914                Binder.restoreCallingIdentity(ident);
9915            }
9916        }
9917    }
9918
9919    @Override
9920    public List<StackInfo> getAllStackInfos() {
9921        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9922        long ident = Binder.clearCallingIdentity();
9923        try {
9924            synchronized (this) {
9925                return mStackSupervisor.getAllStackInfosLocked();
9926            }
9927        } finally {
9928            Binder.restoreCallingIdentity(ident);
9929        }
9930    }
9931
9932    @Override
9933    public StackInfo getStackInfo(int stackId) {
9934        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9935        long ident = Binder.clearCallingIdentity();
9936        try {
9937            synchronized (this) {
9938                return mStackSupervisor.getStackInfoLocked(stackId);
9939            }
9940        } finally {
9941            Binder.restoreCallingIdentity(ident);
9942        }
9943    }
9944
9945    @Override
9946    public boolean isInHomeStack(int taskId) {
9947        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9948        long ident = Binder.clearCallingIdentity();
9949        try {
9950            synchronized (this) {
9951                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9952                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9953                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9954            }
9955        } finally {
9956            Binder.restoreCallingIdentity(ident);
9957        }
9958    }
9959
9960    @Override
9961    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9962        synchronized(this) {
9963            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9964        }
9965    }
9966
9967    @Override
9968    public void updateDeviceOwner(String packageName) {
9969        final int callingUid = Binder.getCallingUid();
9970        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9971            throw new SecurityException("updateDeviceOwner called from non-system process");
9972        }
9973        synchronized (this) {
9974            mDeviceOwnerName = packageName;
9975        }
9976    }
9977
9978    @Override
9979    public void updateLockTaskPackages(int userId, String[] packages) {
9980        final int callingUid = Binder.getCallingUid();
9981        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9982            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9983                    "updateLockTaskPackages()");
9984        }
9985        synchronized (this) {
9986            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9987                    Arrays.toString(packages));
9988            mLockTaskPackages.put(userId, packages);
9989            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9990        }
9991    }
9992
9993
9994    void startLockTaskModeLocked(TaskRecord task) {
9995        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9996        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9997            return;
9998        }
9999
10000        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10001        // is initiated by system after the pinning request was shown and locked mode is initiated
10002        // by an authorized app directly
10003        final int callingUid = Binder.getCallingUid();
10004        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10005        long ident = Binder.clearCallingIdentity();
10006        try {
10007            if (!isSystemInitiated) {
10008                task.mLockTaskUid = callingUid;
10009                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10010                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10011                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10012                    StatusBarManagerInternal statusBarManager =
10013                            LocalServices.getService(StatusBarManagerInternal.class);
10014                    if (statusBarManager != null) {
10015                        statusBarManager.showScreenPinningRequest(task.taskId);
10016                    }
10017                    return;
10018                }
10019
10020                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10021                if (stack == null || task != stack.topTask()) {
10022                    throw new IllegalArgumentException("Invalid task, not in foreground");
10023                }
10024            }
10025            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10026                    "Locking fully");
10027            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10028                    ActivityManager.LOCK_TASK_MODE_PINNED :
10029                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10030                    "startLockTask", true);
10031        } finally {
10032            Binder.restoreCallingIdentity(ident);
10033        }
10034    }
10035
10036    @Override
10037    public void startLockTaskMode(int taskId) {
10038        synchronized (this) {
10039            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10040            if (task != null) {
10041                startLockTaskModeLocked(task);
10042            }
10043        }
10044    }
10045
10046    @Override
10047    public void startLockTaskMode(IBinder token) {
10048        synchronized (this) {
10049            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10050            if (r == null) {
10051                return;
10052            }
10053            final TaskRecord task = r.task;
10054            if (task != null) {
10055                startLockTaskModeLocked(task);
10056            }
10057        }
10058    }
10059
10060    @Override
10061    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10062        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10063        // This makes inner call to look as if it was initiated by system.
10064        long ident = Binder.clearCallingIdentity();
10065        try {
10066            synchronized (this) {
10067                startLockTaskMode(taskId);
10068            }
10069        } finally {
10070            Binder.restoreCallingIdentity(ident);
10071        }
10072    }
10073
10074    @Override
10075    public void stopLockTaskMode() {
10076        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10077        if (lockTask == null) {
10078            // Our work here is done.
10079            return;
10080        }
10081
10082        final int callingUid = Binder.getCallingUid();
10083        final int lockTaskUid = lockTask.mLockTaskUid;
10084        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10085        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10086            // Done.
10087            return;
10088        } else {
10089            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10090            // It is possible lockTaskMode was started by the system process because
10091            // android:lockTaskMode is set to a locking value in the application manifest
10092            // instead of the app calling startLockTaskMode. In this case
10093            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10094            // {@link TaskRecord.effectiveUid} instead. Also caller with
10095            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10096            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10097                    && callingUid != lockTaskUid
10098                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10099                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10100                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10101            }
10102        }
10103        long ident = Binder.clearCallingIdentity();
10104        try {
10105            Log.d(TAG, "stopLockTaskMode");
10106            // Stop lock task
10107            synchronized (this) {
10108                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10109                        "stopLockTask", true);
10110            }
10111        } finally {
10112            Binder.restoreCallingIdentity(ident);
10113        }
10114    }
10115
10116    /**
10117     * This API should be called by SystemUI only when user perform certain action to dismiss
10118     * lock task mode. We should only dismiss pinned lock task mode in this case.
10119     */
10120    @Override
10121    public void stopSystemLockTaskMode() throws RemoteException {
10122        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10123            stopLockTaskMode();
10124        } else {
10125            mStackSupervisor.showLockTaskToast();
10126        }
10127    }
10128
10129    @Override
10130    public boolean isInLockTaskMode() {
10131        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10132    }
10133
10134    @Override
10135    public int getLockTaskModeState() {
10136        synchronized (this) {
10137            return mStackSupervisor.getLockTaskModeState();
10138        }
10139    }
10140
10141    @Override
10142    public void showLockTaskEscapeMessage(IBinder token) {
10143        synchronized (this) {
10144            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10145            if (r == null) {
10146                return;
10147            }
10148            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10149        }
10150    }
10151
10152    // =========================================================
10153    // CONTENT PROVIDERS
10154    // =========================================================
10155
10156    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10157        List<ProviderInfo> providers = null;
10158        try {
10159            providers = AppGlobals.getPackageManager()
10160                    .queryContentProviders(app.processName, app.uid,
10161                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10162                                    | MATCH_DEBUG_TRIAGED_MISSING)
10163                    .getList();
10164        } catch (RemoteException ex) {
10165        }
10166        if (DEBUG_MU) Slog.v(TAG_MU,
10167                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10168        int userId = app.userId;
10169        if (providers != null) {
10170            int N = providers.size();
10171            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10172            for (int i=0; i<N; i++) {
10173                // TODO: keep logic in sync with installEncryptionUnawareProviders
10174                ProviderInfo cpi =
10175                    (ProviderInfo)providers.get(i);
10176                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10177                        cpi.name, cpi.flags);
10178                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10179                    // This is a singleton provider, but a user besides the
10180                    // default user is asking to initialize a process it runs
10181                    // in...  well, no, it doesn't actually run in this process,
10182                    // it runs in the process of the default user.  Get rid of it.
10183                    providers.remove(i);
10184                    N--;
10185                    i--;
10186                    continue;
10187                }
10188
10189                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10190                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10191                if (cpr == null) {
10192                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10193                    mProviderMap.putProviderByClass(comp, cpr);
10194                }
10195                if (DEBUG_MU) Slog.v(TAG_MU,
10196                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10197                app.pubProviders.put(cpi.name, cpr);
10198                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10199                    // Don't add this if it is a platform component that is marked
10200                    // to run in multiple processes, because this is actually
10201                    // part of the framework so doesn't make sense to track as a
10202                    // separate apk in the process.
10203                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10204                            mProcessStats);
10205                }
10206                notifyPackageUse(cpi.applicationInfo.packageName,
10207                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10208            }
10209        }
10210        return providers;
10211    }
10212
10213    /**
10214     * Check if {@link ProcessRecord} has a possible chance at accessing the
10215     * given {@link ProviderInfo}. Final permission checking is always done
10216     * in {@link ContentProvider}.
10217     */
10218    private final String checkContentProviderPermissionLocked(
10219            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10220        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10221        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10222        boolean checkedGrants = false;
10223        if (checkUser) {
10224            // Looking for cross-user grants before enforcing the typical cross-users permissions
10225            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10226            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10227                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10228                    return null;
10229                }
10230                checkedGrants = true;
10231            }
10232            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10233                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10234            if (userId != tmpTargetUserId) {
10235                // When we actually went to determine the final targer user ID, this ended
10236                // up different than our initial check for the authority.  This is because
10237                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10238                // SELF.  So we need to re-check the grants again.
10239                checkedGrants = false;
10240            }
10241        }
10242        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10243                cpi.applicationInfo.uid, cpi.exported)
10244                == PackageManager.PERMISSION_GRANTED) {
10245            return null;
10246        }
10247        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10248                cpi.applicationInfo.uid, cpi.exported)
10249                == PackageManager.PERMISSION_GRANTED) {
10250            return null;
10251        }
10252
10253        PathPermission[] pps = cpi.pathPermissions;
10254        if (pps != null) {
10255            int i = pps.length;
10256            while (i > 0) {
10257                i--;
10258                PathPermission pp = pps[i];
10259                String pprperm = pp.getReadPermission();
10260                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10261                        cpi.applicationInfo.uid, cpi.exported)
10262                        == PackageManager.PERMISSION_GRANTED) {
10263                    return null;
10264                }
10265                String ppwperm = pp.getWritePermission();
10266                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10267                        cpi.applicationInfo.uid, cpi.exported)
10268                        == PackageManager.PERMISSION_GRANTED) {
10269                    return null;
10270                }
10271            }
10272        }
10273        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10274            return null;
10275        }
10276
10277        String msg;
10278        if (!cpi.exported) {
10279            msg = "Permission Denial: opening provider " + cpi.name
10280                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10281                    + ", uid=" + callingUid + ") that is not exported from uid "
10282                    + cpi.applicationInfo.uid;
10283        } else {
10284            msg = "Permission Denial: opening provider " + cpi.name
10285                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10286                    + ", uid=" + callingUid + ") requires "
10287                    + cpi.readPermission + " or " + cpi.writePermission;
10288        }
10289        Slog.w(TAG, msg);
10290        return msg;
10291    }
10292
10293    /**
10294     * Returns if the ContentProvider has granted a uri to callingUid
10295     */
10296    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10297        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10298        if (perms != null) {
10299            for (int i=perms.size()-1; i>=0; i--) {
10300                GrantUri grantUri = perms.keyAt(i);
10301                if (grantUri.sourceUserId == userId || !checkUser) {
10302                    if (matchesProvider(grantUri.uri, cpi)) {
10303                        return true;
10304                    }
10305                }
10306            }
10307        }
10308        return false;
10309    }
10310
10311    /**
10312     * Returns true if the uri authority is one of the authorities specified in the provider.
10313     */
10314    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10315        String uriAuth = uri.getAuthority();
10316        String cpiAuth = cpi.authority;
10317        if (cpiAuth.indexOf(';') == -1) {
10318            return cpiAuth.equals(uriAuth);
10319        }
10320        String[] cpiAuths = cpiAuth.split(";");
10321        int length = cpiAuths.length;
10322        for (int i = 0; i < length; i++) {
10323            if (cpiAuths[i].equals(uriAuth)) return true;
10324        }
10325        return false;
10326    }
10327
10328    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10329            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10330        if (r != null) {
10331            for (int i=0; i<r.conProviders.size(); i++) {
10332                ContentProviderConnection conn = r.conProviders.get(i);
10333                if (conn.provider == cpr) {
10334                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10335                            "Adding provider requested by "
10336                            + r.processName + " from process "
10337                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10338                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10339                    if (stable) {
10340                        conn.stableCount++;
10341                        conn.numStableIncs++;
10342                    } else {
10343                        conn.unstableCount++;
10344                        conn.numUnstableIncs++;
10345                    }
10346                    return conn;
10347                }
10348            }
10349            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10350            if (stable) {
10351                conn.stableCount = 1;
10352                conn.numStableIncs = 1;
10353            } else {
10354                conn.unstableCount = 1;
10355                conn.numUnstableIncs = 1;
10356            }
10357            cpr.connections.add(conn);
10358            r.conProviders.add(conn);
10359            startAssociationLocked(r.uid, r.processName, r.curProcState,
10360                    cpr.uid, cpr.name, cpr.info.processName);
10361            return conn;
10362        }
10363        cpr.addExternalProcessHandleLocked(externalProcessToken);
10364        return null;
10365    }
10366
10367    boolean decProviderCountLocked(ContentProviderConnection conn,
10368            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10369        if (conn != null) {
10370            cpr = conn.provider;
10371            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10372                    "Removing provider requested by "
10373                    + conn.client.processName + " from process "
10374                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10375                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10376            if (stable) {
10377                conn.stableCount--;
10378            } else {
10379                conn.unstableCount--;
10380            }
10381            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10382                cpr.connections.remove(conn);
10383                conn.client.conProviders.remove(conn);
10384                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10385                    // The client is more important than last activity -- note the time this
10386                    // is happening, so we keep the old provider process around a bit as last
10387                    // activity to avoid thrashing it.
10388                    if (cpr.proc != null) {
10389                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10390                    }
10391                }
10392                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10393                return true;
10394            }
10395            return false;
10396        }
10397        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10398        return false;
10399    }
10400
10401    private void checkTime(long startTime, String where) {
10402        long now = SystemClock.uptimeMillis();
10403        if ((now-startTime) > 50) {
10404            // If we are taking more than 50ms, log about it.
10405            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10406        }
10407    }
10408
10409    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10410            String name, IBinder token, boolean stable, int userId) {
10411        ContentProviderRecord cpr;
10412        ContentProviderConnection conn = null;
10413        ProviderInfo cpi = null;
10414
10415        synchronized(this) {
10416            long startTime = SystemClock.uptimeMillis();
10417
10418            ProcessRecord r = null;
10419            if (caller != null) {
10420                r = getRecordForAppLocked(caller);
10421                if (r == null) {
10422                    throw new SecurityException(
10423                            "Unable to find app for caller " + caller
10424                          + " (pid=" + Binder.getCallingPid()
10425                          + ") when getting content provider " + name);
10426                }
10427            }
10428
10429            boolean checkCrossUser = true;
10430
10431            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10432
10433            // First check if this content provider has been published...
10434            cpr = mProviderMap.getProviderByName(name, userId);
10435            // If that didn't work, check if it exists for user 0 and then
10436            // verify that it's a singleton provider before using it.
10437            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10438                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10439                if (cpr != null) {
10440                    cpi = cpr.info;
10441                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10442                            cpi.name, cpi.flags)
10443                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10444                        userId = UserHandle.USER_SYSTEM;
10445                        checkCrossUser = false;
10446                    } else {
10447                        cpr = null;
10448                        cpi = null;
10449                    }
10450                }
10451            }
10452
10453            boolean providerRunning = cpr != null;
10454            if (providerRunning) {
10455                cpi = cpr.info;
10456                String msg;
10457                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10458                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10459                        != null) {
10460                    throw new SecurityException(msg);
10461                }
10462                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10463
10464                if (r != null && cpr.canRunHere(r)) {
10465                    // This provider has been published or is in the process
10466                    // of being published...  but it is also allowed to run
10467                    // in the caller's process, so don't make a connection
10468                    // and just let the caller instantiate its own instance.
10469                    ContentProviderHolder holder = cpr.newHolder(null);
10470                    // don't give caller the provider object, it needs
10471                    // to make its own.
10472                    holder.provider = null;
10473                    return holder;
10474                }
10475
10476                final long origId = Binder.clearCallingIdentity();
10477
10478                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10479
10480                // In this case the provider instance already exists, so we can
10481                // return it right away.
10482                conn = incProviderCountLocked(r, cpr, token, stable);
10483                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10484                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10485                        // If this is a perceptible app accessing the provider,
10486                        // make sure to count it as being accessed and thus
10487                        // back up on the LRU list.  This is good because
10488                        // content providers are often expensive to start.
10489                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10490                        updateLruProcessLocked(cpr.proc, false, null);
10491                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10492                    }
10493                }
10494
10495                if (cpr.proc != null) {
10496                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10497                    boolean success = updateOomAdjLocked(cpr.proc);
10498                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10499                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10500                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10501                    // NOTE: there is still a race here where a signal could be
10502                    // pending on the process even though we managed to update its
10503                    // adj level.  Not sure what to do about this, but at least
10504                    // the race is now smaller.
10505                    if (!success) {
10506                        // Uh oh...  it looks like the provider's process
10507                        // has been killed on us.  We need to wait for a new
10508                        // process to be started, and make sure its death
10509                        // doesn't kill our process.
10510                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10511                                + " is crashing; detaching " + r);
10512                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10513                        checkTime(startTime, "getContentProviderImpl: before appDied");
10514                        appDiedLocked(cpr.proc);
10515                        checkTime(startTime, "getContentProviderImpl: after appDied");
10516                        if (!lastRef) {
10517                            // This wasn't the last ref our process had on
10518                            // the provider...  we have now been killed, bail.
10519                            return null;
10520                        }
10521                        providerRunning = false;
10522                        conn = null;
10523                    }
10524                }
10525
10526                Binder.restoreCallingIdentity(origId);
10527            }
10528
10529            if (!providerRunning) {
10530                try {
10531                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10532                    cpi = AppGlobals.getPackageManager().
10533                        resolveContentProvider(name,
10534                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10535                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10536                } catch (RemoteException ex) {
10537                }
10538                if (cpi == null) {
10539                    return null;
10540                }
10541                // If the provider is a singleton AND
10542                // (it's a call within the same user || the provider is a
10543                // privileged app)
10544                // Then allow connecting to the singleton provider
10545                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10546                        cpi.name, cpi.flags)
10547                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10548                if (singleton) {
10549                    userId = UserHandle.USER_SYSTEM;
10550                }
10551                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10552                checkTime(startTime, "getContentProviderImpl: got app info for user");
10553
10554                String msg;
10555                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10556                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10557                        != null) {
10558                    throw new SecurityException(msg);
10559                }
10560                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10561
10562                if (!mProcessesReady
10563                        && !cpi.processName.equals("system")) {
10564                    // If this content provider does not run in the system
10565                    // process, and the system is not yet ready to run other
10566                    // processes, then fail fast instead of hanging.
10567                    throw new IllegalArgumentException(
10568                            "Attempt to launch content provider before system ready");
10569                }
10570
10571                // Make sure that the user who owns this provider is running.  If not,
10572                // we don't want to allow it to run.
10573                if (!mUserController.isUserRunningLocked(userId, 0)) {
10574                    Slog.w(TAG, "Unable to launch app "
10575                            + cpi.applicationInfo.packageName + "/"
10576                            + cpi.applicationInfo.uid + " for provider "
10577                            + name + ": user " + userId + " is stopped");
10578                    return null;
10579                }
10580
10581                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10582                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10583                cpr = mProviderMap.getProviderByClass(comp, userId);
10584                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10585                final boolean firstClass = cpr == null;
10586                if (firstClass) {
10587                    final long ident = Binder.clearCallingIdentity();
10588
10589                    // If permissions need a review before any of the app components can run,
10590                    // we return no provider and launch a review activity if the calling app
10591                    // is in the foreground.
10592                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10593                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10594                            return null;
10595                        }
10596                    }
10597
10598                    try {
10599                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10600                        ApplicationInfo ai =
10601                            AppGlobals.getPackageManager().
10602                                getApplicationInfo(
10603                                        cpi.applicationInfo.packageName,
10604                                        STOCK_PM_FLAGS, userId);
10605                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10606                        if (ai == null) {
10607                            Slog.w(TAG, "No package info for content provider "
10608                                    + cpi.name);
10609                            return null;
10610                        }
10611                        ai = getAppInfoForUser(ai, userId);
10612                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10613                    } catch (RemoteException ex) {
10614                        // pm is in same process, this will never happen.
10615                    } finally {
10616                        Binder.restoreCallingIdentity(ident);
10617                    }
10618                }
10619
10620                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10621
10622                if (r != null && cpr.canRunHere(r)) {
10623                    // If this is a multiprocess provider, then just return its
10624                    // info and allow the caller to instantiate it.  Only do
10625                    // this if the provider is the same user as the caller's
10626                    // process, or can run as root (so can be in any process).
10627                    return cpr.newHolder(null);
10628                }
10629
10630                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10631                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10632                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10633
10634                // This is single process, and our app is now connecting to it.
10635                // See if we are already in the process of launching this
10636                // provider.
10637                final int N = mLaunchingProviders.size();
10638                int i;
10639                for (i = 0; i < N; i++) {
10640                    if (mLaunchingProviders.get(i) == cpr) {
10641                        break;
10642                    }
10643                }
10644
10645                // If the provider is not already being launched, then get it
10646                // started.
10647                if (i >= N) {
10648                    final long origId = Binder.clearCallingIdentity();
10649
10650                    try {
10651                        // Content provider is now in use, its package can't be stopped.
10652                        try {
10653                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10654                            AppGlobals.getPackageManager().setPackageStoppedState(
10655                                    cpr.appInfo.packageName, false, userId);
10656                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10657                        } catch (RemoteException e) {
10658                        } catch (IllegalArgumentException e) {
10659                            Slog.w(TAG, "Failed trying to unstop package "
10660                                    + cpr.appInfo.packageName + ": " + e);
10661                        }
10662
10663                        // Use existing process if already started
10664                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10665                        ProcessRecord proc = getProcessRecordLocked(
10666                                cpi.processName, cpr.appInfo.uid, false);
10667                        if (proc != null && proc.thread != null) {
10668                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10669                                    "Installing in existing process " + proc);
10670                            if (!proc.pubProviders.containsKey(cpi.name)) {
10671                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10672                                proc.pubProviders.put(cpi.name, cpr);
10673                                try {
10674                                    proc.thread.scheduleInstallProvider(cpi);
10675                                } catch (RemoteException e) {
10676                                }
10677                            }
10678                        } else {
10679                            checkTime(startTime, "getContentProviderImpl: before start process");
10680                            proc = startProcessLocked(cpi.processName,
10681                                    cpr.appInfo, false, 0, "content provider",
10682                                    new ComponentName(cpi.applicationInfo.packageName,
10683                                            cpi.name), false, false, false);
10684                            checkTime(startTime, "getContentProviderImpl: after start process");
10685                            if (proc == null) {
10686                                Slog.w(TAG, "Unable to launch app "
10687                                        + cpi.applicationInfo.packageName + "/"
10688                                        + cpi.applicationInfo.uid + " for provider "
10689                                        + name + ": process is bad");
10690                                return null;
10691                            }
10692                        }
10693                        cpr.launchingApp = proc;
10694                        mLaunchingProviders.add(cpr);
10695                    } finally {
10696                        Binder.restoreCallingIdentity(origId);
10697                    }
10698                }
10699
10700                checkTime(startTime, "getContentProviderImpl: updating data structures");
10701
10702                // Make sure the provider is published (the same provider class
10703                // may be published under multiple names).
10704                if (firstClass) {
10705                    mProviderMap.putProviderByClass(comp, cpr);
10706                }
10707
10708                mProviderMap.putProviderByName(name, cpr);
10709                conn = incProviderCountLocked(r, cpr, token, stable);
10710                if (conn != null) {
10711                    conn.waiting = true;
10712                }
10713            }
10714            checkTime(startTime, "getContentProviderImpl: done!");
10715        }
10716
10717        // Wait for the provider to be published...
10718        synchronized (cpr) {
10719            while (cpr.provider == null) {
10720                if (cpr.launchingApp == null) {
10721                    Slog.w(TAG, "Unable to launch app "
10722                            + cpi.applicationInfo.packageName + "/"
10723                            + cpi.applicationInfo.uid + " for provider "
10724                            + name + ": launching app became null");
10725                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10726                            UserHandle.getUserId(cpi.applicationInfo.uid),
10727                            cpi.applicationInfo.packageName,
10728                            cpi.applicationInfo.uid, name);
10729                    return null;
10730                }
10731                try {
10732                    if (DEBUG_MU) Slog.v(TAG_MU,
10733                            "Waiting to start provider " + cpr
10734                            + " launchingApp=" + cpr.launchingApp);
10735                    if (conn != null) {
10736                        conn.waiting = true;
10737                    }
10738                    cpr.wait();
10739                } catch (InterruptedException ex) {
10740                } finally {
10741                    if (conn != null) {
10742                        conn.waiting = false;
10743                    }
10744                }
10745            }
10746        }
10747        return cpr != null ? cpr.newHolder(conn) : null;
10748    }
10749
10750    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10751            ProcessRecord r, final int userId) {
10752        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10753                cpi.packageName, userId)) {
10754
10755            final boolean callerForeground = r == null || r.setSchedGroup
10756                    != ProcessList.SCHED_GROUP_BACKGROUND;
10757
10758            // Show a permission review UI only for starting from a foreground app
10759            if (!callerForeground) {
10760                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10761                        + cpi.packageName + " requires a permissions review");
10762                return false;
10763            }
10764
10765            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10766            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10767                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10768            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10769
10770            if (DEBUG_PERMISSIONS_REVIEW) {
10771                Slog.i(TAG, "u" + userId + " Launching permission review "
10772                        + "for package " + cpi.packageName);
10773            }
10774
10775            final UserHandle userHandle = new UserHandle(userId);
10776            mHandler.post(new Runnable() {
10777                @Override
10778                public void run() {
10779                    mContext.startActivityAsUser(intent, userHandle);
10780                }
10781            });
10782
10783            return false;
10784        }
10785
10786        return true;
10787    }
10788
10789    PackageManagerInternal getPackageManagerInternalLocked() {
10790        if (mPackageManagerInt == null) {
10791            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10792        }
10793        return mPackageManagerInt;
10794    }
10795
10796    @Override
10797    public final ContentProviderHolder getContentProvider(
10798            IApplicationThread caller, String name, int userId, boolean stable) {
10799        enforceNotIsolatedCaller("getContentProvider");
10800        if (caller == null) {
10801            String msg = "null IApplicationThread when getting content provider "
10802                    + name;
10803            Slog.w(TAG, msg);
10804            throw new SecurityException(msg);
10805        }
10806        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10807        // with cross-user grant.
10808        return getContentProviderImpl(caller, name, null, stable, userId);
10809    }
10810
10811    public ContentProviderHolder getContentProviderExternal(
10812            String name, int userId, IBinder token) {
10813        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10814            "Do not have permission in call getContentProviderExternal()");
10815        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10816                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10817        return getContentProviderExternalUnchecked(name, token, userId);
10818    }
10819
10820    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10821            IBinder token, int userId) {
10822        return getContentProviderImpl(null, name, token, true, userId);
10823    }
10824
10825    /**
10826     * Drop a content provider from a ProcessRecord's bookkeeping
10827     */
10828    public void removeContentProvider(IBinder connection, boolean stable) {
10829        enforceNotIsolatedCaller("removeContentProvider");
10830        long ident = Binder.clearCallingIdentity();
10831        try {
10832            synchronized (this) {
10833                ContentProviderConnection conn;
10834                try {
10835                    conn = (ContentProviderConnection)connection;
10836                } catch (ClassCastException e) {
10837                    String msg ="removeContentProvider: " + connection
10838                            + " not a ContentProviderConnection";
10839                    Slog.w(TAG, msg);
10840                    throw new IllegalArgumentException(msg);
10841                }
10842                if (conn == null) {
10843                    throw new NullPointerException("connection is null");
10844                }
10845                if (decProviderCountLocked(conn, null, null, stable)) {
10846                    updateOomAdjLocked();
10847                }
10848            }
10849        } finally {
10850            Binder.restoreCallingIdentity(ident);
10851        }
10852    }
10853
10854    public void removeContentProviderExternal(String name, IBinder token) {
10855        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10856            "Do not have permission in call removeContentProviderExternal()");
10857        int userId = UserHandle.getCallingUserId();
10858        long ident = Binder.clearCallingIdentity();
10859        try {
10860            removeContentProviderExternalUnchecked(name, token, userId);
10861        } finally {
10862            Binder.restoreCallingIdentity(ident);
10863        }
10864    }
10865
10866    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10867        synchronized (this) {
10868            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10869            if(cpr == null) {
10870                //remove from mProvidersByClass
10871                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10872                return;
10873            }
10874
10875            //update content provider record entry info
10876            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10877            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10878            if (localCpr.hasExternalProcessHandles()) {
10879                if (localCpr.removeExternalProcessHandleLocked(token)) {
10880                    updateOomAdjLocked();
10881                } else {
10882                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10883                            + " with no external reference for token: "
10884                            + token + ".");
10885                }
10886            } else {
10887                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10888                        + " with no external references.");
10889            }
10890        }
10891    }
10892
10893    public final void publishContentProviders(IApplicationThread caller,
10894            List<ContentProviderHolder> providers) {
10895        if (providers == null) {
10896            return;
10897        }
10898
10899        enforceNotIsolatedCaller("publishContentProviders");
10900        synchronized (this) {
10901            final ProcessRecord r = getRecordForAppLocked(caller);
10902            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10903            if (r == null) {
10904                throw new SecurityException(
10905                        "Unable to find app for caller " + caller
10906                      + " (pid=" + Binder.getCallingPid()
10907                      + ") when publishing content providers");
10908            }
10909
10910            final long origId = Binder.clearCallingIdentity();
10911
10912            final int N = providers.size();
10913            for (int i = 0; i < N; i++) {
10914                ContentProviderHolder src = providers.get(i);
10915                if (src == null || src.info == null || src.provider == null) {
10916                    continue;
10917                }
10918                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10919                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10920                if (dst != null) {
10921                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10922                    mProviderMap.putProviderByClass(comp, dst);
10923                    String names[] = dst.info.authority.split(";");
10924                    for (int j = 0; j < names.length; j++) {
10925                        mProviderMap.putProviderByName(names[j], dst);
10926                    }
10927
10928                    int launchingCount = mLaunchingProviders.size();
10929                    int j;
10930                    boolean wasInLaunchingProviders = false;
10931                    for (j = 0; j < launchingCount; j++) {
10932                        if (mLaunchingProviders.get(j) == dst) {
10933                            mLaunchingProviders.remove(j);
10934                            wasInLaunchingProviders = true;
10935                            j--;
10936                            launchingCount--;
10937                        }
10938                    }
10939                    if (wasInLaunchingProviders) {
10940                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10941                    }
10942                    synchronized (dst) {
10943                        dst.provider = src.provider;
10944                        dst.proc = r;
10945                        dst.notifyAll();
10946                    }
10947                    updateOomAdjLocked(r);
10948                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10949                            src.info.authority);
10950                }
10951            }
10952
10953            Binder.restoreCallingIdentity(origId);
10954        }
10955    }
10956
10957    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10958        ContentProviderConnection conn;
10959        try {
10960            conn = (ContentProviderConnection)connection;
10961        } catch (ClassCastException e) {
10962            String msg ="refContentProvider: " + connection
10963                    + " not a ContentProviderConnection";
10964            Slog.w(TAG, msg);
10965            throw new IllegalArgumentException(msg);
10966        }
10967        if (conn == null) {
10968            throw new NullPointerException("connection is null");
10969        }
10970
10971        synchronized (this) {
10972            if (stable > 0) {
10973                conn.numStableIncs += stable;
10974            }
10975            stable = conn.stableCount + stable;
10976            if (stable < 0) {
10977                throw new IllegalStateException("stableCount < 0: " + stable);
10978            }
10979
10980            if (unstable > 0) {
10981                conn.numUnstableIncs += unstable;
10982            }
10983            unstable = conn.unstableCount + unstable;
10984            if (unstable < 0) {
10985                throw new IllegalStateException("unstableCount < 0: " + unstable);
10986            }
10987
10988            if ((stable+unstable) <= 0) {
10989                throw new IllegalStateException("ref counts can't go to zero here: stable="
10990                        + stable + " unstable=" + unstable);
10991            }
10992            conn.stableCount = stable;
10993            conn.unstableCount = unstable;
10994            return !conn.dead;
10995        }
10996    }
10997
10998    public void unstableProviderDied(IBinder connection) {
10999        ContentProviderConnection conn;
11000        try {
11001            conn = (ContentProviderConnection)connection;
11002        } catch (ClassCastException e) {
11003            String msg ="refContentProvider: " + connection
11004                    + " not a ContentProviderConnection";
11005            Slog.w(TAG, msg);
11006            throw new IllegalArgumentException(msg);
11007        }
11008        if (conn == null) {
11009            throw new NullPointerException("connection is null");
11010        }
11011
11012        // Safely retrieve the content provider associated with the connection.
11013        IContentProvider provider;
11014        synchronized (this) {
11015            provider = conn.provider.provider;
11016        }
11017
11018        if (provider == null) {
11019            // Um, yeah, we're way ahead of you.
11020            return;
11021        }
11022
11023        // Make sure the caller is being honest with us.
11024        if (provider.asBinder().pingBinder()) {
11025            // Er, no, still looks good to us.
11026            synchronized (this) {
11027                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11028                        + " says " + conn + " died, but we don't agree");
11029                return;
11030            }
11031        }
11032
11033        // Well look at that!  It's dead!
11034        synchronized (this) {
11035            if (conn.provider.provider != provider) {
11036                // But something changed...  good enough.
11037                return;
11038            }
11039
11040            ProcessRecord proc = conn.provider.proc;
11041            if (proc == null || proc.thread == null) {
11042                // Seems like the process is already cleaned up.
11043                return;
11044            }
11045
11046            // As far as we're concerned, this is just like receiving a
11047            // death notification...  just a bit prematurely.
11048            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11049                    + ") early provider death");
11050            final long ident = Binder.clearCallingIdentity();
11051            try {
11052                appDiedLocked(proc);
11053            } finally {
11054                Binder.restoreCallingIdentity(ident);
11055            }
11056        }
11057    }
11058
11059    @Override
11060    public void appNotRespondingViaProvider(IBinder connection) {
11061        enforceCallingPermission(
11062                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11063
11064        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11065        if (conn == null) {
11066            Slog.w(TAG, "ContentProviderConnection is null");
11067            return;
11068        }
11069
11070        final ProcessRecord host = conn.provider.proc;
11071        if (host == null) {
11072            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11073            return;
11074        }
11075
11076        mHandler.post(new Runnable() {
11077            @Override
11078            public void run() {
11079                mAppErrors.appNotResponding(host, null, null, false,
11080                        "ContentProvider not responding");
11081            }
11082        });
11083    }
11084
11085    public final void installSystemProviders() {
11086        List<ProviderInfo> providers;
11087        synchronized (this) {
11088            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11089            providers = generateApplicationProvidersLocked(app);
11090            if (providers != null) {
11091                for (int i=providers.size()-1; i>=0; i--) {
11092                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11093                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11094                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11095                                + ": not system .apk");
11096                        providers.remove(i);
11097                    }
11098                }
11099            }
11100        }
11101        if (providers != null) {
11102            mSystemThread.installSystemProviders(providers);
11103        }
11104
11105        mCoreSettingsObserver = new CoreSettingsObserver(this);
11106        mFontScaleSettingObserver = new FontScaleSettingObserver();
11107
11108        //mUsageStatsService.monitorPackages();
11109    }
11110
11111    private void startPersistentApps(int matchFlags) {
11112        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11113
11114        synchronized (this) {
11115            try {
11116                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11117                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11118                for (ApplicationInfo app : apps) {
11119                    if (!"android".equals(app.packageName)) {
11120                        addAppLocked(app, false, null /* ABI override */);
11121                    }
11122                }
11123            } catch (RemoteException ex) {
11124            }
11125        }
11126    }
11127
11128    /**
11129     * When a user is unlocked, we need to install encryption-unaware providers
11130     * belonging to any running apps.
11131     */
11132    private void installEncryptionUnawareProviders(int userId) {
11133        // We're only interested in providers that are encryption unaware, and
11134        // we don't care about uninstalled apps, since there's no way they're
11135        // running at this point.
11136        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11137
11138        synchronized (this) {
11139            final int NP = mProcessNames.getMap().size();
11140            for (int ip = 0; ip < NP; ip++) {
11141                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11142                final int NA = apps.size();
11143                for (int ia = 0; ia < NA; ia++) {
11144                    final ProcessRecord app = apps.valueAt(ia);
11145                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11146
11147                    final int NG = app.pkgList.size();
11148                    for (int ig = 0; ig < NG; ig++) {
11149                        try {
11150                            final String pkgName = app.pkgList.keyAt(ig);
11151                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11152                                    .getPackageInfo(pkgName, matchFlags, userId);
11153                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11154                                for (ProviderInfo pi : pkgInfo.providers) {
11155                                    // TODO: keep in sync with generateApplicationProvidersLocked
11156                                    final boolean processMatch = Objects.equals(pi.processName,
11157                                            app.processName) || pi.multiprocess;
11158                                    final boolean userMatch = isSingleton(pi.processName,
11159                                            pi.applicationInfo, pi.name, pi.flags)
11160                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11161                                    if (processMatch && userMatch) {
11162                                        Log.v(TAG, "Installing " + pi);
11163                                        app.thread.scheduleInstallProvider(pi);
11164                                    } else {
11165                                        Log.v(TAG, "Skipping " + pi);
11166                                    }
11167                                }
11168                            }
11169                        } catch (RemoteException ignored) {
11170                        }
11171                    }
11172                }
11173            }
11174        }
11175    }
11176
11177    /**
11178     * Allows apps to retrieve the MIME type of a URI.
11179     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11180     * users, then it does not need permission to access the ContentProvider.
11181     * Either, it needs cross-user uri grants.
11182     *
11183     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11184     *
11185     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11186     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11187     */
11188    public String getProviderMimeType(Uri uri, int userId) {
11189        enforceNotIsolatedCaller("getProviderMimeType");
11190        final String name = uri.getAuthority();
11191        int callingUid = Binder.getCallingUid();
11192        int callingPid = Binder.getCallingPid();
11193        long ident = 0;
11194        boolean clearedIdentity = false;
11195        synchronized (this) {
11196            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11197        }
11198        if (canClearIdentity(callingPid, callingUid, userId)) {
11199            clearedIdentity = true;
11200            ident = Binder.clearCallingIdentity();
11201        }
11202        ContentProviderHolder holder = null;
11203        try {
11204            holder = getContentProviderExternalUnchecked(name, null, userId);
11205            if (holder != null) {
11206                return holder.provider.getType(uri);
11207            }
11208        } catch (RemoteException e) {
11209            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11210            return null;
11211        } finally {
11212            // We need to clear the identity to call removeContentProviderExternalUnchecked
11213            if (!clearedIdentity) {
11214                ident = Binder.clearCallingIdentity();
11215            }
11216            try {
11217                if (holder != null) {
11218                    removeContentProviderExternalUnchecked(name, null, userId);
11219                }
11220            } finally {
11221                Binder.restoreCallingIdentity(ident);
11222            }
11223        }
11224
11225        return null;
11226    }
11227
11228    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11229        if (UserHandle.getUserId(callingUid) == userId) {
11230            return true;
11231        }
11232        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11233                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11234                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11235                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11236                return true;
11237        }
11238        return false;
11239    }
11240
11241    // =========================================================
11242    // GLOBAL MANAGEMENT
11243    // =========================================================
11244
11245    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11246            boolean isolated, int isolatedUid) {
11247        String proc = customProcess != null ? customProcess : info.processName;
11248        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11249        final int userId = UserHandle.getUserId(info.uid);
11250        int uid = info.uid;
11251        if (isolated) {
11252            if (isolatedUid == 0) {
11253                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11254                while (true) {
11255                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11256                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11257                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11258                    }
11259                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11260                    mNextIsolatedProcessUid++;
11261                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11262                        // No process for this uid, use it.
11263                        break;
11264                    }
11265                    stepsLeft--;
11266                    if (stepsLeft <= 0) {
11267                        return null;
11268                    }
11269                }
11270            } else {
11271                // Special case for startIsolatedProcess (internal only), where
11272                // the uid of the isolated process is specified by the caller.
11273                uid = isolatedUid;
11274            }
11275        }
11276        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11277        if (!mBooted && !mBooting
11278                && userId == UserHandle.USER_SYSTEM
11279                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11280            r.persistent = true;
11281        }
11282        addProcessNameLocked(r);
11283        return r;
11284    }
11285
11286    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11287            String abiOverride) {
11288        ProcessRecord app;
11289        if (!isolated) {
11290            app = getProcessRecordLocked(info.processName, info.uid, true);
11291        } else {
11292            app = null;
11293        }
11294
11295        if (app == null) {
11296            app = newProcessRecordLocked(info, null, isolated, 0);
11297            updateLruProcessLocked(app, false, null);
11298            updateOomAdjLocked();
11299        }
11300
11301        // This package really, really can not be stopped.
11302        try {
11303            AppGlobals.getPackageManager().setPackageStoppedState(
11304                    info.packageName, false, UserHandle.getUserId(app.uid));
11305        } catch (RemoteException e) {
11306        } catch (IllegalArgumentException e) {
11307            Slog.w(TAG, "Failed trying to unstop package "
11308                    + info.packageName + ": " + e);
11309        }
11310
11311        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11312            app.persistent = true;
11313            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11314        }
11315        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11316            mPersistentStartingProcesses.add(app);
11317            startProcessLocked(app, "added application", app.processName, abiOverride,
11318                    null /* entryPoint */, null /* entryPointArgs */);
11319        }
11320
11321        return app;
11322    }
11323
11324    public void unhandledBack() {
11325        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11326                "unhandledBack()");
11327
11328        synchronized(this) {
11329            final long origId = Binder.clearCallingIdentity();
11330            try {
11331                getFocusedStack().unhandledBackLocked();
11332            } finally {
11333                Binder.restoreCallingIdentity(origId);
11334            }
11335        }
11336    }
11337
11338    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11339        enforceNotIsolatedCaller("openContentUri");
11340        final int userId = UserHandle.getCallingUserId();
11341        String name = uri.getAuthority();
11342        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11343        ParcelFileDescriptor pfd = null;
11344        if (cph != null) {
11345            // We record the binder invoker's uid in thread-local storage before
11346            // going to the content provider to open the file.  Later, in the code
11347            // that handles all permissions checks, we look for this uid and use
11348            // that rather than the Activity Manager's own uid.  The effect is that
11349            // we do the check against the caller's permissions even though it looks
11350            // to the content provider like the Activity Manager itself is making
11351            // the request.
11352            Binder token = new Binder();
11353            sCallerIdentity.set(new Identity(
11354                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11355            try {
11356                pfd = cph.provider.openFile(null, uri, "r", null, token);
11357            } catch (FileNotFoundException e) {
11358                // do nothing; pfd will be returned null
11359            } finally {
11360                // Ensure that whatever happens, we clean up the identity state
11361                sCallerIdentity.remove();
11362                // Ensure we're done with the provider.
11363                removeContentProviderExternalUnchecked(name, null, userId);
11364            }
11365        } else {
11366            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11367        }
11368        return pfd;
11369    }
11370
11371    // Actually is sleeping or shutting down or whatever else in the future
11372    // is an inactive state.
11373    public boolean isSleepingOrShuttingDown() {
11374        return isSleeping() || mShuttingDown;
11375    }
11376
11377    public boolean isSleeping() {
11378        return mSleeping;
11379    }
11380
11381    void onWakefulnessChanged(int wakefulness) {
11382        synchronized(this) {
11383            mWakefulness = wakefulness;
11384            updateSleepIfNeededLocked();
11385        }
11386    }
11387
11388    void finishRunningVoiceLocked() {
11389        if (mRunningVoice != null) {
11390            mRunningVoice = null;
11391            mVoiceWakeLock.release();
11392            updateSleepIfNeededLocked();
11393        }
11394    }
11395
11396    void startTimeTrackingFocusedActivityLocked() {
11397        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11398            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11399        }
11400    }
11401
11402    void updateSleepIfNeededLocked() {
11403        if (mSleeping && !shouldSleepLocked()) {
11404            mSleeping = false;
11405            startTimeTrackingFocusedActivityLocked();
11406            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11407            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11408            updateOomAdjLocked();
11409        } else if (!mSleeping && shouldSleepLocked()) {
11410            mSleeping = true;
11411            if (mCurAppTimeTracker != null) {
11412                mCurAppTimeTracker.stop();
11413            }
11414            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11415            mStackSupervisor.goingToSleepLocked();
11416            updateOomAdjLocked();
11417
11418            // Initialize the wake times of all processes.
11419            checkExcessivePowerUsageLocked(false);
11420            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11421            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11422            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11423        }
11424    }
11425
11426    private boolean shouldSleepLocked() {
11427        // Resume applications while running a voice interactor.
11428        if (mRunningVoice != null) {
11429            return false;
11430        }
11431
11432        // TODO: Transform the lock screen state into a sleep token instead.
11433        switch (mWakefulness) {
11434            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11435            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11436            case PowerManagerInternal.WAKEFULNESS_DOZING:
11437                // Pause applications whenever the lock screen is shown or any sleep
11438                // tokens have been acquired.
11439                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11440            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11441            default:
11442                // If we're asleep then pause applications unconditionally.
11443                return true;
11444        }
11445    }
11446
11447    /** Pokes the task persister. */
11448    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11449        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11450    }
11451
11452    /** Notifies all listeners when the task stack has changed. */
11453    void notifyTaskStackChangedLocked() {
11454        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11455        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11456        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11457        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11458    }
11459
11460    /** Notifies all listeners when an Activity is pinned. */
11461    void notifyActivityPinnedLocked() {
11462        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11463        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11464    }
11465
11466    /**
11467     * Notifies all listeners when an attempt was made to start an an activity that is already
11468     * running in the pinned stack and the activity was not actually started, but the task is
11469     * either brought to the front or a new Intent is delivered to it.
11470     */
11471    void notifyPinnedActivityRestartAttemptLocked() {
11472        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11473        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11474    }
11475
11476    /** Notifies all listeners when the pinned stack animation ends. */
11477    @Override
11478    public void notifyPinnedStackAnimationEnded() {
11479        synchronized (this) {
11480            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11481            mHandler.obtainMessage(
11482                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11483        }
11484    }
11485
11486    @Override
11487    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11488        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11489    }
11490
11491    @Override
11492    public boolean shutdown(int timeout) {
11493        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11494                != PackageManager.PERMISSION_GRANTED) {
11495            throw new SecurityException("Requires permission "
11496                    + android.Manifest.permission.SHUTDOWN);
11497        }
11498
11499        boolean timedout = false;
11500
11501        synchronized(this) {
11502            mShuttingDown = true;
11503            updateEventDispatchingLocked();
11504            timedout = mStackSupervisor.shutdownLocked(timeout);
11505        }
11506
11507        mAppOpsService.shutdown();
11508        if (mUsageStatsService != null) {
11509            mUsageStatsService.prepareShutdown();
11510        }
11511        mBatteryStatsService.shutdown();
11512        synchronized (this) {
11513            mProcessStats.shutdownLocked();
11514            notifyTaskPersisterLocked(null, true);
11515        }
11516
11517        return timedout;
11518    }
11519
11520    public final void activitySlept(IBinder token) {
11521        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11522
11523        final long origId = Binder.clearCallingIdentity();
11524
11525        synchronized (this) {
11526            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11527            if (r != null) {
11528                mStackSupervisor.activitySleptLocked(r);
11529            }
11530        }
11531
11532        Binder.restoreCallingIdentity(origId);
11533    }
11534
11535    private String lockScreenShownToString() {
11536        switch (mLockScreenShown) {
11537            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11538            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11539            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11540            default: return "Unknown=" + mLockScreenShown;
11541        }
11542    }
11543
11544    void logLockScreen(String msg) {
11545        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11546                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11547                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11548                + " mSleeping=" + mSleeping);
11549    }
11550
11551    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11552        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11553        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11554        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11555            boolean wasRunningVoice = mRunningVoice != null;
11556            mRunningVoice = session;
11557            if (!wasRunningVoice) {
11558                mVoiceWakeLock.acquire();
11559                updateSleepIfNeededLocked();
11560            }
11561        }
11562    }
11563
11564    private void updateEventDispatchingLocked() {
11565        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11566    }
11567
11568    public void setLockScreenShown(boolean showing, boolean occluded) {
11569        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11570                != PackageManager.PERMISSION_GRANTED) {
11571            throw new SecurityException("Requires permission "
11572                    + android.Manifest.permission.DEVICE_POWER);
11573        }
11574
11575        synchronized(this) {
11576            long ident = Binder.clearCallingIdentity();
11577            try {
11578                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11579                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11580                if (showing && occluded) {
11581                    // The lock screen is currently showing, but is occluded by a window that can
11582                    // show on top of the lock screen. In this can we want to dismiss the docked
11583                    // stack since it will be complicated/risky to try to put the activity on top
11584                    // of the lock screen in the right fullscreen configuration.
11585                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11586                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11587                }
11588
11589                updateSleepIfNeededLocked();
11590            } finally {
11591                Binder.restoreCallingIdentity(ident);
11592            }
11593        }
11594    }
11595
11596    @Override
11597    public void notifyLockedProfile(@UserIdInt int userId) {
11598        try {
11599            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11600                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11601            }
11602        } catch (RemoteException ex) {
11603            throw new SecurityException("Fail to check is caller a privileged app", ex);
11604        }
11605
11606        synchronized (this) {
11607            if (mStackSupervisor.isUserLockedProfile(userId)) {
11608                final long ident = Binder.clearCallingIdentity();
11609                try {
11610                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11611                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11612                        // If there is no device lock, we will show the profile's credential page.
11613                        mActivityStarter.showConfirmDeviceCredential(userId);
11614                    } else {
11615                        // Showing launcher to avoid user entering credential twice.
11616                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11617                    }
11618                } finally {
11619                    Binder.restoreCallingIdentity(ident);
11620                }
11621            }
11622        }
11623    }
11624
11625    @Override
11626    public void startConfirmDeviceCredentialIntent(Intent intent) {
11627        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11628        synchronized (this) {
11629            final long ident = Binder.clearCallingIdentity();
11630            try {
11631                mActivityStarter.startConfirmCredentialIntent(intent);
11632            } finally {
11633                Binder.restoreCallingIdentity(ident);
11634            }
11635        }
11636    }
11637
11638    @Override
11639    public void stopAppSwitches() {
11640        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11641                != PackageManager.PERMISSION_GRANTED) {
11642            throw new SecurityException("viewquires permission "
11643                    + android.Manifest.permission.STOP_APP_SWITCHES);
11644        }
11645
11646        synchronized(this) {
11647            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11648                    + APP_SWITCH_DELAY_TIME;
11649            mDidAppSwitch = false;
11650            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11651            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11652            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11653        }
11654    }
11655
11656    public void resumeAppSwitches() {
11657        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11658                != PackageManager.PERMISSION_GRANTED) {
11659            throw new SecurityException("Requires permission "
11660                    + android.Manifest.permission.STOP_APP_SWITCHES);
11661        }
11662
11663        synchronized(this) {
11664            // Note that we don't execute any pending app switches... we will
11665            // let those wait until either the timeout, or the next start
11666            // activity request.
11667            mAppSwitchesAllowedTime = 0;
11668        }
11669    }
11670
11671    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11672            int callingPid, int callingUid, String name) {
11673        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11674            return true;
11675        }
11676
11677        int perm = checkComponentPermission(
11678                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11679                sourceUid, -1, true);
11680        if (perm == PackageManager.PERMISSION_GRANTED) {
11681            return true;
11682        }
11683
11684        // If the actual IPC caller is different from the logical source, then
11685        // also see if they are allowed to control app switches.
11686        if (callingUid != -1 && callingUid != sourceUid) {
11687            perm = checkComponentPermission(
11688                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11689                    callingUid, -1, true);
11690            if (perm == PackageManager.PERMISSION_GRANTED) {
11691                return true;
11692            }
11693        }
11694
11695        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11696        return false;
11697    }
11698
11699    public void setDebugApp(String packageName, boolean waitForDebugger,
11700            boolean persistent) {
11701        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11702                "setDebugApp()");
11703
11704        long ident = Binder.clearCallingIdentity();
11705        try {
11706            // Note that this is not really thread safe if there are multiple
11707            // callers into it at the same time, but that's not a situation we
11708            // care about.
11709            if (persistent) {
11710                final ContentResolver resolver = mContext.getContentResolver();
11711                Settings.Global.putString(
11712                    resolver, Settings.Global.DEBUG_APP,
11713                    packageName);
11714                Settings.Global.putInt(
11715                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11716                    waitForDebugger ? 1 : 0);
11717            }
11718
11719            synchronized (this) {
11720                if (!persistent) {
11721                    mOrigDebugApp = mDebugApp;
11722                    mOrigWaitForDebugger = mWaitForDebugger;
11723                }
11724                mDebugApp = packageName;
11725                mWaitForDebugger = waitForDebugger;
11726                mDebugTransient = !persistent;
11727                if (packageName != null) {
11728                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11729                            false, UserHandle.USER_ALL, "set debug app");
11730                }
11731            }
11732        } finally {
11733            Binder.restoreCallingIdentity(ident);
11734        }
11735    }
11736
11737    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11738        synchronized (this) {
11739            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11740            if (!isDebuggable) {
11741                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11742                    throw new SecurityException("Process not debuggable: " + app.packageName);
11743                }
11744            }
11745
11746            mTrackAllocationApp = processName;
11747        }
11748    }
11749
11750    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11751        synchronized (this) {
11752            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11753            if (!isDebuggable) {
11754                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11755                    throw new SecurityException("Process not debuggable: " + app.packageName);
11756                }
11757            }
11758            mProfileApp = processName;
11759            mProfileFile = profilerInfo.profileFile;
11760            if (mProfileFd != null) {
11761                try {
11762                    mProfileFd.close();
11763                } catch (IOException e) {
11764                }
11765                mProfileFd = null;
11766            }
11767            mProfileFd = profilerInfo.profileFd;
11768            mSamplingInterval = profilerInfo.samplingInterval;
11769            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11770            mProfileType = 0;
11771        }
11772    }
11773
11774    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11775        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11776        if (!isDebuggable) {
11777            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11778                throw new SecurityException("Process not debuggable: " + app.packageName);
11779            }
11780        }
11781        mNativeDebuggingApp = processName;
11782    }
11783
11784    @Override
11785    public void setAlwaysFinish(boolean enabled) {
11786        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11787                "setAlwaysFinish()");
11788
11789        long ident = Binder.clearCallingIdentity();
11790        try {
11791            Settings.Global.putInt(
11792                    mContext.getContentResolver(),
11793                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11794
11795            synchronized (this) {
11796                mAlwaysFinishActivities = enabled;
11797            }
11798        } finally {
11799            Binder.restoreCallingIdentity(ident);
11800        }
11801    }
11802
11803    @Override
11804    public void setLenientBackgroundCheck(boolean enabled) {
11805        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11806                "setLenientBackgroundCheck()");
11807
11808        long ident = Binder.clearCallingIdentity();
11809        try {
11810            Settings.Global.putInt(
11811                    mContext.getContentResolver(),
11812                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11813
11814            synchronized (this) {
11815                mLenientBackgroundCheck = enabled;
11816            }
11817        } finally {
11818            Binder.restoreCallingIdentity(ident);
11819        }
11820    }
11821
11822    @Override
11823    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11824        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11825                "setActivityController()");
11826        synchronized (this) {
11827            mController = controller;
11828            mControllerIsAMonkey = imAMonkey;
11829            Watchdog.getInstance().setActivityController(controller);
11830        }
11831    }
11832
11833    @Override
11834    public void setUserIsMonkey(boolean userIsMonkey) {
11835        synchronized (this) {
11836            synchronized (mPidsSelfLocked) {
11837                final int callingPid = Binder.getCallingPid();
11838                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11839                if (precessRecord == null) {
11840                    throw new SecurityException("Unknown process: " + callingPid);
11841                }
11842                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11843                    throw new SecurityException("Only an instrumentation process "
11844                            + "with a UiAutomation can call setUserIsMonkey");
11845                }
11846            }
11847            mUserIsMonkey = userIsMonkey;
11848        }
11849    }
11850
11851    @Override
11852    public boolean isUserAMonkey() {
11853        synchronized (this) {
11854            // If there is a controller also implies the user is a monkey.
11855            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11856        }
11857    }
11858
11859    public void requestBugReport(int bugreportType) {
11860        String service = null;
11861        switch (bugreportType) {
11862            case ActivityManager.BUGREPORT_OPTION_FULL:
11863                service = "bugreport";
11864                break;
11865            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11866                service = "bugreportplus";
11867                break;
11868            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11869                service = "bugreportremote";
11870                break;
11871        }
11872        if (service == null) {
11873            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11874                    + bugreportType);
11875        }
11876        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11877        SystemProperties.set("ctl.start", service);
11878    }
11879
11880    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11881        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11882    }
11883
11884    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11885        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11886            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11887        }
11888        return KEY_DISPATCHING_TIMEOUT;
11889    }
11890
11891    @Override
11892    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11893        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11894                != PackageManager.PERMISSION_GRANTED) {
11895            throw new SecurityException("Requires permission "
11896                    + android.Manifest.permission.FILTER_EVENTS);
11897        }
11898        ProcessRecord proc;
11899        long timeout;
11900        synchronized (this) {
11901            synchronized (mPidsSelfLocked) {
11902                proc = mPidsSelfLocked.get(pid);
11903            }
11904            timeout = getInputDispatchingTimeoutLocked(proc);
11905        }
11906
11907        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11908            return -1;
11909        }
11910
11911        return timeout;
11912    }
11913
11914    /**
11915     * Handle input dispatching timeouts.
11916     * Returns whether input dispatching should be aborted or not.
11917     */
11918    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11919            final ActivityRecord activity, final ActivityRecord parent,
11920            final boolean aboveSystem, String reason) {
11921        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11922                != PackageManager.PERMISSION_GRANTED) {
11923            throw new SecurityException("Requires permission "
11924                    + android.Manifest.permission.FILTER_EVENTS);
11925        }
11926
11927        final String annotation;
11928        if (reason == null) {
11929            annotation = "Input dispatching timed out";
11930        } else {
11931            annotation = "Input dispatching timed out (" + reason + ")";
11932        }
11933
11934        if (proc != null) {
11935            synchronized (this) {
11936                if (proc.debugging) {
11937                    return false;
11938                }
11939
11940                if (mDidDexOpt) {
11941                    // Give more time since we were dexopting.
11942                    mDidDexOpt = false;
11943                    return false;
11944                }
11945
11946                if (proc.instrumentationClass != null) {
11947                    Bundle info = new Bundle();
11948                    info.putString("shortMsg", "keyDispatchingTimedOut");
11949                    info.putString("longMsg", annotation);
11950                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11951                    return true;
11952                }
11953            }
11954            mHandler.post(new Runnable() {
11955                @Override
11956                public void run() {
11957                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11958                }
11959            });
11960        }
11961
11962        return true;
11963    }
11964
11965    @Override
11966    public Bundle getAssistContextExtras(int requestType) {
11967        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11968                null, null, true /* focused */, true /* newSessionId */,
11969                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11970        if (pae == null) {
11971            return null;
11972        }
11973        synchronized (pae) {
11974            while (!pae.haveResult) {
11975                try {
11976                    pae.wait();
11977                } catch (InterruptedException e) {
11978                }
11979            }
11980        }
11981        synchronized (this) {
11982            buildAssistBundleLocked(pae, pae.result);
11983            mPendingAssistExtras.remove(pae);
11984            mUiHandler.removeCallbacks(pae);
11985        }
11986        return pae.extras;
11987    }
11988
11989    @Override
11990    public boolean isAssistDataAllowedOnCurrentActivity() {
11991        int userId;
11992        synchronized (this) {
11993            userId = mUserController.getCurrentUserIdLocked();
11994            ActivityRecord activity = getFocusedStack().topActivity();
11995            if (activity == null) {
11996                return false;
11997            }
11998            userId = activity.userId;
11999        }
12000        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12001                Context.DEVICE_POLICY_SERVICE);
12002        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12003    }
12004
12005    @Override
12006    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12007        long ident = Binder.clearCallingIdentity();
12008        try {
12009            synchronized (this) {
12010                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12011                ActivityRecord top = getFocusedStack().topActivity();
12012                if (top != caller) {
12013                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12014                            + " is not current top " + top);
12015                    return false;
12016                }
12017                if (!top.nowVisible) {
12018                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12019                            + " is not visible");
12020                    return false;
12021                }
12022            }
12023            AssistUtils utils = new AssistUtils(mContext);
12024            return utils.showSessionForActiveService(args,
12025                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12026        } finally {
12027            Binder.restoreCallingIdentity(ident);
12028        }
12029    }
12030
12031    @Override
12032    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12033            Bundle receiverExtras,
12034            IBinder activityToken, boolean focused, boolean newSessionId) {
12035        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12036                activityToken, focused, newSessionId,
12037                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12038                != null;
12039    }
12040
12041    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12042            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12043            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12044        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12045                "enqueueAssistContext()");
12046        synchronized (this) {
12047            ActivityRecord activity = getFocusedStack().topActivity();
12048            if (activity == null) {
12049                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12050                return null;
12051            }
12052            if (activity.app == null || activity.app.thread == null) {
12053                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12054                return null;
12055            }
12056            if (focused) {
12057                if (activityToken != null) {
12058                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12059                    if (activity != caller) {
12060                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12061                                + " is not current top " + activity);
12062                        return null;
12063                    }
12064                }
12065            } else {
12066                activity = ActivityRecord.forTokenLocked(activityToken);
12067                if (activity == null) {
12068                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12069                            + " couldn't be found");
12070                    return null;
12071                }
12072            }
12073
12074            PendingAssistExtras pae;
12075            Bundle extras = new Bundle();
12076            if (args != null) {
12077                extras.putAll(args);
12078            }
12079            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12080            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12081            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12082                    userHandle);
12083            // Increment the sessionId if necessary
12084            if (newSessionId) {
12085                mViSessionId++;
12086            }
12087            try {
12088                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12089                        requestType, mViSessionId);
12090                mPendingAssistExtras.add(pae);
12091                mUiHandler.postDelayed(pae, timeout);
12092            } catch (RemoteException e) {
12093                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12094                return null;
12095            }
12096            return pae;
12097        }
12098    }
12099
12100    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12101        IResultReceiver receiver;
12102        synchronized (this) {
12103            mPendingAssistExtras.remove(pae);
12104            receiver = pae.receiver;
12105        }
12106        if (receiver != null) {
12107            // Caller wants result sent back to them.
12108            Bundle sendBundle = new Bundle();
12109            // At least return the receiver extras
12110            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12111                    pae.receiverExtras);
12112            try {
12113                pae.receiver.send(0, sendBundle);
12114            } catch (RemoteException e) {
12115            }
12116        }
12117    }
12118
12119    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12120        if (result != null) {
12121            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12122        }
12123        if (pae.hint != null) {
12124            pae.extras.putBoolean(pae.hint, true);
12125        }
12126    }
12127
12128    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12129            AssistContent content, Uri referrer) {
12130        PendingAssistExtras pae = (PendingAssistExtras)token;
12131        synchronized (pae) {
12132            pae.result = extras;
12133            pae.structure = structure;
12134            pae.content = content;
12135            if (referrer != null) {
12136                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12137            }
12138            pae.haveResult = true;
12139            pae.notifyAll();
12140            if (pae.intent == null && pae.receiver == null) {
12141                // Caller is just waiting for the result.
12142                return;
12143            }
12144        }
12145
12146        // We are now ready to launch the assist activity.
12147        IResultReceiver sendReceiver = null;
12148        Bundle sendBundle = null;
12149        synchronized (this) {
12150            buildAssistBundleLocked(pae, extras);
12151            boolean exists = mPendingAssistExtras.remove(pae);
12152            mUiHandler.removeCallbacks(pae);
12153            if (!exists) {
12154                // Timed out.
12155                return;
12156            }
12157            if ((sendReceiver=pae.receiver) != null) {
12158                // Caller wants result sent back to them.
12159                sendBundle = new Bundle();
12160                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12161                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12162                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12163                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12164                        pae.receiverExtras);
12165            }
12166        }
12167        if (sendReceiver != null) {
12168            try {
12169                sendReceiver.send(0, sendBundle);
12170            } catch (RemoteException e) {
12171            }
12172            return;
12173        }
12174
12175        long ident = Binder.clearCallingIdentity();
12176        try {
12177            pae.intent.replaceExtras(pae.extras);
12178            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12179                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12180                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12181            closeSystemDialogs("assist");
12182            try {
12183                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12184            } catch (ActivityNotFoundException e) {
12185                Slog.w(TAG, "No activity to handle assist action.", e);
12186            }
12187        } finally {
12188            Binder.restoreCallingIdentity(ident);
12189        }
12190    }
12191
12192    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12193            Bundle args) {
12194        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12195                true /* focused */, true /* newSessionId */,
12196                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12197    }
12198
12199    public void registerProcessObserver(IProcessObserver observer) {
12200        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12201                "registerProcessObserver()");
12202        synchronized (this) {
12203            mProcessObservers.register(observer);
12204        }
12205    }
12206
12207    @Override
12208    public void unregisterProcessObserver(IProcessObserver observer) {
12209        synchronized (this) {
12210            mProcessObservers.unregister(observer);
12211        }
12212    }
12213
12214    @Override
12215    public void registerUidObserver(IUidObserver observer, int which) {
12216        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12217                "registerUidObserver()");
12218        synchronized (this) {
12219            mUidObservers.register(observer, which);
12220        }
12221    }
12222
12223    @Override
12224    public void unregisterUidObserver(IUidObserver observer) {
12225        synchronized (this) {
12226            mUidObservers.unregister(observer);
12227        }
12228    }
12229
12230    @Override
12231    public boolean convertFromTranslucent(IBinder token) {
12232        final long origId = Binder.clearCallingIdentity();
12233        try {
12234            synchronized (this) {
12235                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12236                if (r == null) {
12237                    return false;
12238                }
12239                final boolean translucentChanged = r.changeWindowTranslucency(true);
12240                if (translucentChanged) {
12241                    r.task.stack.releaseBackgroundResources(r);
12242                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12243                }
12244                mWindowManager.setAppFullscreen(token, true);
12245                return translucentChanged;
12246            }
12247        } finally {
12248            Binder.restoreCallingIdentity(origId);
12249        }
12250    }
12251
12252    @Override
12253    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12254        final long origId = Binder.clearCallingIdentity();
12255        try {
12256            synchronized (this) {
12257                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12258                if (r == null) {
12259                    return false;
12260                }
12261                int index = r.task.mActivities.lastIndexOf(r);
12262                if (index > 0) {
12263                    ActivityRecord under = r.task.mActivities.get(index - 1);
12264                    under.returningOptions = options;
12265                }
12266                final boolean translucentChanged = r.changeWindowTranslucency(false);
12267                if (translucentChanged) {
12268                    r.task.stack.convertActivityToTranslucent(r);
12269                }
12270                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12271                mWindowManager.setAppFullscreen(token, false);
12272                return translucentChanged;
12273            }
12274        } finally {
12275            Binder.restoreCallingIdentity(origId);
12276        }
12277    }
12278
12279    @Override
12280    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12281        final long origId = Binder.clearCallingIdentity();
12282        try {
12283            synchronized (this) {
12284                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12285                if (r != null) {
12286                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12287                }
12288            }
12289            return false;
12290        } finally {
12291            Binder.restoreCallingIdentity(origId);
12292        }
12293    }
12294
12295    @Override
12296    public boolean isBackgroundVisibleBehind(IBinder token) {
12297        final long origId = Binder.clearCallingIdentity();
12298        try {
12299            synchronized (this) {
12300                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12301                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12302                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12303                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12304                return visible;
12305            }
12306        } finally {
12307            Binder.restoreCallingIdentity(origId);
12308        }
12309    }
12310
12311    @Override
12312    public ActivityOptions getActivityOptions(IBinder token) {
12313        final long origId = Binder.clearCallingIdentity();
12314        try {
12315            synchronized (this) {
12316                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12317                if (r != null) {
12318                    final ActivityOptions activityOptions = r.pendingOptions;
12319                    r.pendingOptions = null;
12320                    return activityOptions;
12321                }
12322                return null;
12323            }
12324        } finally {
12325            Binder.restoreCallingIdentity(origId);
12326        }
12327    }
12328
12329    @Override
12330    public void setImmersive(IBinder token, boolean immersive) {
12331        synchronized(this) {
12332            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12333            if (r == null) {
12334                throw new IllegalArgumentException();
12335            }
12336            r.immersive = immersive;
12337
12338            // update associated state if we're frontmost
12339            if (r == mFocusedActivity) {
12340                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12341                applyUpdateLockStateLocked(r);
12342            }
12343        }
12344    }
12345
12346    @Override
12347    public boolean isImmersive(IBinder token) {
12348        synchronized (this) {
12349            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12350            if (r == null) {
12351                throw new IllegalArgumentException();
12352            }
12353            return r.immersive;
12354        }
12355    }
12356
12357    @Override
12358    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12359        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12360            throw new UnsupportedOperationException("VR mode not supported on this device!");
12361        }
12362
12363        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12364
12365        ActivityRecord r;
12366        synchronized (this) {
12367            r = ActivityRecord.isInStackLocked(token);
12368        }
12369
12370        if (r == null) {
12371            throw new IllegalArgumentException();
12372        }
12373
12374        int err;
12375        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12376                VrManagerInternal.NO_ERROR) {
12377            return err;
12378        }
12379
12380        synchronized(this) {
12381            r.requestedVrComponent = (enabled) ? packageName : null;
12382
12383            // Update associated state if this activity is currently focused
12384            if (r == mFocusedActivity) {
12385                applyUpdateVrModeLocked(r);
12386            }
12387            return 0;
12388        }
12389    }
12390
12391    @Override
12392    public boolean isVrModePackageEnabled(ComponentName packageName) {
12393        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12394            throw new UnsupportedOperationException("VR mode not supported on this device!");
12395        }
12396
12397        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12398
12399        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12400                VrManagerInternal.NO_ERROR;
12401    }
12402
12403    public boolean isTopActivityImmersive() {
12404        enforceNotIsolatedCaller("startActivity");
12405        synchronized (this) {
12406            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12407            return (r != null) ? r.immersive : false;
12408        }
12409    }
12410
12411    @Override
12412    public boolean isTopOfTask(IBinder token) {
12413        synchronized (this) {
12414            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12415            if (r == null) {
12416                throw new IllegalArgumentException();
12417            }
12418            return r.task.getTopActivity() == r;
12419        }
12420    }
12421
12422    public final void enterSafeMode() {
12423        synchronized(this) {
12424            // It only makes sense to do this before the system is ready
12425            // and started launching other packages.
12426            if (!mSystemReady) {
12427                try {
12428                    AppGlobals.getPackageManager().enterSafeMode();
12429                } catch (RemoteException e) {
12430                }
12431            }
12432
12433            mSafeMode = true;
12434        }
12435    }
12436
12437    public final void showSafeModeOverlay() {
12438        View v = LayoutInflater.from(mContext).inflate(
12439                com.android.internal.R.layout.safe_mode, null);
12440        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12441        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12442        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12443        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12444        lp.gravity = Gravity.BOTTOM | Gravity.START;
12445        lp.format = v.getBackground().getOpacity();
12446        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12447                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12448        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12449        ((WindowManager)mContext.getSystemService(
12450                Context.WINDOW_SERVICE)).addView(v, lp);
12451    }
12452
12453    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12454        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12455            return;
12456        }
12457        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12458        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12459        synchronized (stats) {
12460            if (mBatteryStatsService.isOnBattery()) {
12461                mBatteryStatsService.enforceCallingPermission();
12462                int MY_UID = Binder.getCallingUid();
12463                final int uid;
12464                if (sender == null) {
12465                    uid = sourceUid;
12466                } else {
12467                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12468                }
12469                BatteryStatsImpl.Uid.Pkg pkg =
12470                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12471                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12472                pkg.noteWakeupAlarmLocked(tag);
12473            }
12474        }
12475    }
12476
12477    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12478        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12479            return;
12480        }
12481        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12482        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12483        synchronized (stats) {
12484            mBatteryStatsService.enforceCallingPermission();
12485            int MY_UID = Binder.getCallingUid();
12486            final int uid;
12487            if (sender == null) {
12488                uid = sourceUid;
12489            } else {
12490                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12491            }
12492            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12493        }
12494    }
12495
12496    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12497        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12498            return;
12499        }
12500        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12501        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12502        synchronized (stats) {
12503            mBatteryStatsService.enforceCallingPermission();
12504            int MY_UID = Binder.getCallingUid();
12505            final int uid;
12506            if (sender == null) {
12507                uid = sourceUid;
12508            } else {
12509                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12510            }
12511            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12512        }
12513    }
12514
12515    public boolean killPids(int[] pids, String pReason, boolean secure) {
12516        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12517            throw new SecurityException("killPids only available to the system");
12518        }
12519        String reason = (pReason == null) ? "Unknown" : pReason;
12520        // XXX Note: don't acquire main activity lock here, because the window
12521        // manager calls in with its locks held.
12522
12523        boolean killed = false;
12524        synchronized (mPidsSelfLocked) {
12525            int worstType = 0;
12526            for (int i=0; i<pids.length; i++) {
12527                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12528                if (proc != null) {
12529                    int type = proc.setAdj;
12530                    if (type > worstType) {
12531                        worstType = type;
12532                    }
12533                }
12534            }
12535
12536            // If the worst oom_adj is somewhere in the cached proc LRU range,
12537            // then constrain it so we will kill all cached procs.
12538            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12539                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12540                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12541            }
12542
12543            // If this is not a secure call, don't let it kill processes that
12544            // are important.
12545            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12546                worstType = ProcessList.SERVICE_ADJ;
12547            }
12548
12549            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12550            for (int i=0; i<pids.length; i++) {
12551                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12552                if (proc == null) {
12553                    continue;
12554                }
12555                int adj = proc.setAdj;
12556                if (adj >= worstType && !proc.killedByAm) {
12557                    proc.kill(reason, true);
12558                    killed = true;
12559                }
12560            }
12561        }
12562        return killed;
12563    }
12564
12565    @Override
12566    public void killUid(int appId, int userId, String reason) {
12567        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12568        synchronized (this) {
12569            final long identity = Binder.clearCallingIdentity();
12570            try {
12571                killPackageProcessesLocked(null, appId, userId,
12572                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12573                        reason != null ? reason : "kill uid");
12574            } finally {
12575                Binder.restoreCallingIdentity(identity);
12576            }
12577        }
12578    }
12579
12580    @Override
12581    public boolean killProcessesBelowForeground(String reason) {
12582        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12583            throw new SecurityException("killProcessesBelowForeground() only available to system");
12584        }
12585
12586        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12587    }
12588
12589    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12590        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12591            throw new SecurityException("killProcessesBelowAdj() only available to system");
12592        }
12593
12594        boolean killed = false;
12595        synchronized (mPidsSelfLocked) {
12596            final int size = mPidsSelfLocked.size();
12597            for (int i = 0; i < size; i++) {
12598                final int pid = mPidsSelfLocked.keyAt(i);
12599                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12600                if (proc == null) continue;
12601
12602                final int adj = proc.setAdj;
12603                if (adj > belowAdj && !proc.killedByAm) {
12604                    proc.kill(reason, true);
12605                    killed = true;
12606                }
12607            }
12608        }
12609        return killed;
12610    }
12611
12612    @Override
12613    public void hang(final IBinder who, boolean allowRestart) {
12614        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12615                != PackageManager.PERMISSION_GRANTED) {
12616            throw new SecurityException("Requires permission "
12617                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12618        }
12619
12620        final IBinder.DeathRecipient death = new DeathRecipient() {
12621            @Override
12622            public void binderDied() {
12623                synchronized (this) {
12624                    notifyAll();
12625                }
12626            }
12627        };
12628
12629        try {
12630            who.linkToDeath(death, 0);
12631        } catch (RemoteException e) {
12632            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12633            return;
12634        }
12635
12636        synchronized (this) {
12637            Watchdog.getInstance().setAllowRestart(allowRestart);
12638            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12639            synchronized (death) {
12640                while (who.isBinderAlive()) {
12641                    try {
12642                        death.wait();
12643                    } catch (InterruptedException e) {
12644                    }
12645                }
12646            }
12647            Watchdog.getInstance().setAllowRestart(true);
12648        }
12649    }
12650
12651    @Override
12652    public void restart() {
12653        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12654                != PackageManager.PERMISSION_GRANTED) {
12655            throw new SecurityException("Requires permission "
12656                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12657        }
12658
12659        Log.i(TAG, "Sending shutdown broadcast...");
12660
12661        BroadcastReceiver br = new BroadcastReceiver() {
12662            @Override public void onReceive(Context context, Intent intent) {
12663                // Now the broadcast is done, finish up the low-level shutdown.
12664                Log.i(TAG, "Shutting down activity manager...");
12665                shutdown(10000);
12666                Log.i(TAG, "Shutdown complete, restarting!");
12667                Process.killProcess(Process.myPid());
12668                System.exit(10);
12669            }
12670        };
12671
12672        // First send the high-level shut down broadcast.
12673        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12674        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12675        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12676        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12677        mContext.sendOrderedBroadcastAsUser(intent,
12678                UserHandle.ALL, null, br, mHandler, 0, null, null);
12679        */
12680        br.onReceive(mContext, intent);
12681    }
12682
12683    private long getLowRamTimeSinceIdle(long now) {
12684        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12685    }
12686
12687    @Override
12688    public void performIdleMaintenance() {
12689        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12690                != PackageManager.PERMISSION_GRANTED) {
12691            throw new SecurityException("Requires permission "
12692                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12693        }
12694
12695        synchronized (this) {
12696            final long now = SystemClock.uptimeMillis();
12697            final long timeSinceLastIdle = now - mLastIdleTime;
12698            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12699            mLastIdleTime = now;
12700            mLowRamTimeSinceLastIdle = 0;
12701            if (mLowRamStartTime != 0) {
12702                mLowRamStartTime = now;
12703            }
12704
12705            StringBuilder sb = new StringBuilder(128);
12706            sb.append("Idle maintenance over ");
12707            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12708            sb.append(" low RAM for ");
12709            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12710            Slog.i(TAG, sb.toString());
12711
12712            // If at least 1/3 of our time since the last idle period has been spent
12713            // with RAM low, then we want to kill processes.
12714            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12715
12716            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12717                ProcessRecord proc = mLruProcesses.get(i);
12718                if (proc.notCachedSinceIdle) {
12719                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12720                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12721                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12722                        if (doKilling && proc.initialIdlePss != 0
12723                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12724                            sb = new StringBuilder(128);
12725                            sb.append("Kill");
12726                            sb.append(proc.processName);
12727                            sb.append(" in idle maint: pss=");
12728                            sb.append(proc.lastPss);
12729                            sb.append(", swapPss=");
12730                            sb.append(proc.lastSwapPss);
12731                            sb.append(", initialPss=");
12732                            sb.append(proc.initialIdlePss);
12733                            sb.append(", period=");
12734                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12735                            sb.append(", lowRamPeriod=");
12736                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12737                            Slog.wtfQuiet(TAG, sb.toString());
12738                            proc.kill("idle maint (pss " + proc.lastPss
12739                                    + " from " + proc.initialIdlePss + ")", true);
12740                        }
12741                    }
12742                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12743                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12744                    proc.notCachedSinceIdle = true;
12745                    proc.initialIdlePss = 0;
12746                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12747                            mTestPssMode, isSleeping(), now);
12748                }
12749            }
12750
12751            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12752            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12753        }
12754    }
12755
12756    @Override
12757    public void sendIdleJobTrigger() {
12758        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12759                != PackageManager.PERMISSION_GRANTED) {
12760            throw new SecurityException("Requires permission "
12761                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12762        }
12763
12764        final long ident = Binder.clearCallingIdentity();
12765        try {
12766            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12767                    .setPackage("android")
12768                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12769            broadcastIntent(null, intent, null, null, 0, null, null, null,
12770                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12771        } finally {
12772            Binder.restoreCallingIdentity(ident);
12773        }
12774    }
12775
12776    private void retrieveSettings() {
12777        final ContentResolver resolver = mContext.getContentResolver();
12778        final boolean freeformWindowManagement =
12779                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12780                        || Settings.Global.getInt(
12781                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12782        final boolean supportsPictureInPicture =
12783                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12784
12785        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12786        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12787        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12788        final boolean alwaysFinishActivities =
12789                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12790        final boolean lenientBackgroundCheck =
12791                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12792        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12793        final boolean forceResizable = Settings.Global.getInt(
12794                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12795        // Transfer any global setting for forcing RTL layout, into a System Property
12796        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12797
12798        final Configuration configuration = new Configuration();
12799        Settings.System.getConfiguration(resolver, configuration);
12800        if (forceRtl) {
12801            // This will take care of setting the correct layout direction flags
12802            configuration.setLayoutDirection(configuration.locale);
12803        }
12804
12805        synchronized (this) {
12806            mDebugApp = mOrigDebugApp = debugApp;
12807            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12808            mAlwaysFinishActivities = alwaysFinishActivities;
12809            mLenientBackgroundCheck = lenientBackgroundCheck;
12810            mForceResizableActivities = forceResizable;
12811            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12812            if (supportsMultiWindow || forceResizable) {
12813                mSupportsMultiWindow = true;
12814                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12815                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12816            } else {
12817                mSupportsMultiWindow = false;
12818                mSupportsFreeformWindowManagement = false;
12819                mSupportsPictureInPicture = false;
12820            }
12821            // This happens before any activities are started, so we can
12822            // change mConfiguration in-place.
12823            updateConfigurationLocked(configuration, null, true);
12824            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12825                    "Initial config: " + mConfiguration);
12826
12827            // Load resources only after the current configuration has been set.
12828            final Resources res = mContext.getResources();
12829            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12830            mThumbnailWidth = res.getDimensionPixelSize(
12831                    com.android.internal.R.dimen.thumbnail_width);
12832            mThumbnailHeight = res.getDimensionPixelSize(
12833                    com.android.internal.R.dimen.thumbnail_height);
12834            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12835                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12836            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12837                    com.android.internal.R.string.config_appsNotReportingCrashes));
12838            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12839                mFullscreenThumbnailScale = (float) res
12840                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12841                    (float) mConfiguration.screenWidthDp;
12842            } else {
12843                mFullscreenThumbnailScale = res.getFraction(
12844                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12845            }
12846        }
12847    }
12848
12849    public boolean testIsSystemReady() {
12850        // no need to synchronize(this) just to read & return the value
12851        return mSystemReady;
12852    }
12853
12854    public void systemReady(final Runnable goingCallback) {
12855        synchronized(this) {
12856            if (mSystemReady) {
12857                // If we're done calling all the receivers, run the next "boot phase" passed in
12858                // by the SystemServer
12859                if (goingCallback != null) {
12860                    goingCallback.run();
12861                }
12862                return;
12863            }
12864
12865            mLocalDeviceIdleController
12866                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12867
12868            // Make sure we have the current profile info, since it is needed for security checks.
12869            mUserController.onSystemReady();
12870            mRecentTasks.onSystemReadyLocked();
12871            mAppOpsService.systemReady();
12872            mSystemReady = true;
12873        }
12874
12875        ArrayList<ProcessRecord> procsToKill = null;
12876        synchronized(mPidsSelfLocked) {
12877            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12878                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12879                if (!isAllowedWhileBooting(proc.info)){
12880                    if (procsToKill == null) {
12881                        procsToKill = new ArrayList<ProcessRecord>();
12882                    }
12883                    procsToKill.add(proc);
12884                }
12885            }
12886        }
12887
12888        synchronized(this) {
12889            if (procsToKill != null) {
12890                for (int i=procsToKill.size()-1; i>=0; i--) {
12891                    ProcessRecord proc = procsToKill.get(i);
12892                    Slog.i(TAG, "Removing system update proc: " + proc);
12893                    removeProcessLocked(proc, true, false, "system update done");
12894                }
12895            }
12896
12897            // Now that we have cleaned up any update processes, we
12898            // are ready to start launching real processes and know that
12899            // we won't trample on them any more.
12900            mProcessesReady = true;
12901        }
12902
12903        Slog.i(TAG, "System now ready");
12904        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12905            SystemClock.uptimeMillis());
12906
12907        synchronized(this) {
12908            // Make sure we have no pre-ready processes sitting around.
12909
12910            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12911                ResolveInfo ri = mContext.getPackageManager()
12912                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12913                                STOCK_PM_FLAGS);
12914                CharSequence errorMsg = null;
12915                if (ri != null) {
12916                    ActivityInfo ai = ri.activityInfo;
12917                    ApplicationInfo app = ai.applicationInfo;
12918                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12919                        mTopAction = Intent.ACTION_FACTORY_TEST;
12920                        mTopData = null;
12921                        mTopComponent = new ComponentName(app.packageName,
12922                                ai.name);
12923                    } else {
12924                        errorMsg = mContext.getResources().getText(
12925                                com.android.internal.R.string.factorytest_not_system);
12926                    }
12927                } else {
12928                    errorMsg = mContext.getResources().getText(
12929                            com.android.internal.R.string.factorytest_no_action);
12930                }
12931                if (errorMsg != null) {
12932                    mTopAction = null;
12933                    mTopData = null;
12934                    mTopComponent = null;
12935                    Message msg = Message.obtain();
12936                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12937                    msg.getData().putCharSequence("msg", errorMsg);
12938                    mUiHandler.sendMessage(msg);
12939                }
12940            }
12941        }
12942
12943        retrieveSettings();
12944        final int currentUserId;
12945        synchronized (this) {
12946            currentUserId = mUserController.getCurrentUserIdLocked();
12947            readGrantedUriPermissionsLocked();
12948        }
12949
12950        if (goingCallback != null) goingCallback.run();
12951
12952        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12953                Integer.toString(currentUserId), currentUserId);
12954        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12955                Integer.toString(currentUserId), currentUserId);
12956        mSystemServiceManager.startUser(currentUserId);
12957
12958        synchronized (this) {
12959            // Only start up encryption-aware persistent apps; once user is
12960            // unlocked we'll come back around and start unaware apps
12961            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12962
12963            // Start up initial activity.
12964            mBooting = true;
12965            // Enable home activity for system user, so that the system can always boot
12966            if (UserManager.isSplitSystemUser()) {
12967                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12968                try {
12969                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12970                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12971                            UserHandle.USER_SYSTEM);
12972                } catch (RemoteException e) {
12973                    throw e.rethrowAsRuntimeException();
12974                }
12975            }
12976            startHomeActivityLocked(currentUserId, "systemReady");
12977
12978            try {
12979                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12980                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12981                            + " data partition or your device will be unstable.");
12982                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12983                }
12984            } catch (RemoteException e) {
12985            }
12986
12987            if (!Build.isBuildConsistent()) {
12988                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12989                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12990            }
12991
12992            long ident = Binder.clearCallingIdentity();
12993            try {
12994                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12995                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12996                        | Intent.FLAG_RECEIVER_FOREGROUND);
12997                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12998                broadcastIntentLocked(null, null, intent,
12999                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13000                        null, false, false, MY_PID, Process.SYSTEM_UID,
13001                        currentUserId);
13002                intent = new Intent(Intent.ACTION_USER_STARTING);
13003                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13004                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13005                broadcastIntentLocked(null, null, intent,
13006                        null, new IIntentReceiver.Stub() {
13007                            @Override
13008                            public void performReceive(Intent intent, int resultCode, String data,
13009                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13010                                    throws RemoteException {
13011                            }
13012                        }, 0, null, null,
13013                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13014                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13015            } catch (Throwable t) {
13016                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13017            } finally {
13018                Binder.restoreCallingIdentity(ident);
13019            }
13020            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13021            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13022        }
13023    }
13024
13025    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13026        synchronized (this) {
13027            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13028        }
13029    }
13030
13031    void skipCurrentReceiverLocked(ProcessRecord app) {
13032        for (BroadcastQueue queue : mBroadcastQueues) {
13033            queue.skipCurrentReceiverLocked(app);
13034        }
13035    }
13036
13037    /**
13038     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13039     * The application process will exit immediately after this call returns.
13040     * @param app object of the crashing app, null for the system server
13041     * @param crashInfo describing the exception
13042     */
13043    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13044        ProcessRecord r = findAppProcess(app, "Crash");
13045        final String processName = app == null ? "system_server"
13046                : (r == null ? "unknown" : r.processName);
13047
13048        handleApplicationCrashInner("crash", r, processName, crashInfo);
13049    }
13050
13051    /* Native crash reporting uses this inner version because it needs to be somewhat
13052     * decoupled from the AM-managed cleanup lifecycle
13053     */
13054    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13055            ApplicationErrorReport.CrashInfo crashInfo) {
13056        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13057                UserHandle.getUserId(Binder.getCallingUid()), processName,
13058                r == null ? -1 : r.info.flags,
13059                crashInfo.exceptionClassName,
13060                crashInfo.exceptionMessage,
13061                crashInfo.throwFileName,
13062                crashInfo.throwLineNumber);
13063
13064        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13065
13066        mAppErrors.crashApplication(r, crashInfo);
13067    }
13068
13069    public void handleApplicationStrictModeViolation(
13070            IBinder app,
13071            int violationMask,
13072            StrictMode.ViolationInfo info) {
13073        ProcessRecord r = findAppProcess(app, "StrictMode");
13074        if (r == null) {
13075            return;
13076        }
13077
13078        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13079            Integer stackFingerprint = info.hashCode();
13080            boolean logIt = true;
13081            synchronized (mAlreadyLoggedViolatedStacks) {
13082                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13083                    logIt = false;
13084                    // TODO: sub-sample into EventLog for these, with
13085                    // the info.durationMillis?  Then we'd get
13086                    // the relative pain numbers, without logging all
13087                    // the stack traces repeatedly.  We'd want to do
13088                    // likewise in the client code, which also does
13089                    // dup suppression, before the Binder call.
13090                } else {
13091                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13092                        mAlreadyLoggedViolatedStacks.clear();
13093                    }
13094                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13095                }
13096            }
13097            if (logIt) {
13098                logStrictModeViolationToDropBox(r, info);
13099            }
13100        }
13101
13102        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13103            AppErrorResult result = new AppErrorResult();
13104            synchronized (this) {
13105                final long origId = Binder.clearCallingIdentity();
13106
13107                Message msg = Message.obtain();
13108                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13109                HashMap<String, Object> data = new HashMap<String, Object>();
13110                data.put("result", result);
13111                data.put("app", r);
13112                data.put("violationMask", violationMask);
13113                data.put("info", info);
13114                msg.obj = data;
13115                mUiHandler.sendMessage(msg);
13116
13117                Binder.restoreCallingIdentity(origId);
13118            }
13119            int res = result.get();
13120            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13121        }
13122    }
13123
13124    // Depending on the policy in effect, there could be a bunch of
13125    // these in quick succession so we try to batch these together to
13126    // minimize disk writes, number of dropbox entries, and maximize
13127    // compression, by having more fewer, larger records.
13128    private void logStrictModeViolationToDropBox(
13129            ProcessRecord process,
13130            StrictMode.ViolationInfo info) {
13131        if (info == null) {
13132            return;
13133        }
13134        final boolean isSystemApp = process == null ||
13135                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13136                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13137        final String processName = process == null ? "unknown" : process.processName;
13138        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13139        final DropBoxManager dbox = (DropBoxManager)
13140                mContext.getSystemService(Context.DROPBOX_SERVICE);
13141
13142        // Exit early if the dropbox isn't configured to accept this report type.
13143        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13144
13145        boolean bufferWasEmpty;
13146        boolean needsFlush;
13147        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13148        synchronized (sb) {
13149            bufferWasEmpty = sb.length() == 0;
13150            appendDropBoxProcessHeaders(process, processName, sb);
13151            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13152            sb.append("System-App: ").append(isSystemApp).append("\n");
13153            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13154            if (info.violationNumThisLoop != 0) {
13155                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13156            }
13157            if (info.numAnimationsRunning != 0) {
13158                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13159            }
13160            if (info.broadcastIntentAction != null) {
13161                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13162            }
13163            if (info.durationMillis != -1) {
13164                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13165            }
13166            if (info.numInstances != -1) {
13167                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13168            }
13169            if (info.tags != null) {
13170                for (String tag : info.tags) {
13171                    sb.append("Span-Tag: ").append(tag).append("\n");
13172                }
13173            }
13174            sb.append("\n");
13175            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13176                sb.append(info.crashInfo.stackTrace);
13177                sb.append("\n");
13178            }
13179            if (info.message != null) {
13180                sb.append(info.message);
13181                sb.append("\n");
13182            }
13183
13184            // Only buffer up to ~64k.  Various logging bits truncate
13185            // things at 128k.
13186            needsFlush = (sb.length() > 64 * 1024);
13187        }
13188
13189        // Flush immediately if the buffer's grown too large, or this
13190        // is a non-system app.  Non-system apps are isolated with a
13191        // different tag & policy and not batched.
13192        //
13193        // Batching is useful during internal testing with
13194        // StrictMode settings turned up high.  Without batching,
13195        // thousands of separate files could be created on boot.
13196        if (!isSystemApp || needsFlush) {
13197            new Thread("Error dump: " + dropboxTag) {
13198                @Override
13199                public void run() {
13200                    String report;
13201                    synchronized (sb) {
13202                        report = sb.toString();
13203                        sb.delete(0, sb.length());
13204                        sb.trimToSize();
13205                    }
13206                    if (report.length() != 0) {
13207                        dbox.addText(dropboxTag, report);
13208                    }
13209                }
13210            }.start();
13211            return;
13212        }
13213
13214        // System app batching:
13215        if (!bufferWasEmpty) {
13216            // An existing dropbox-writing thread is outstanding, so
13217            // we don't need to start it up.  The existing thread will
13218            // catch the buffer appends we just did.
13219            return;
13220        }
13221
13222        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13223        // (After this point, we shouldn't access AMS internal data structures.)
13224        new Thread("Error dump: " + dropboxTag) {
13225            @Override
13226            public void run() {
13227                // 5 second sleep to let stacks arrive and be batched together
13228                try {
13229                    Thread.sleep(5000);  // 5 seconds
13230                } catch (InterruptedException e) {}
13231
13232                String errorReport;
13233                synchronized (mStrictModeBuffer) {
13234                    errorReport = mStrictModeBuffer.toString();
13235                    if (errorReport.length() == 0) {
13236                        return;
13237                    }
13238                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13239                    mStrictModeBuffer.trimToSize();
13240                }
13241                dbox.addText(dropboxTag, errorReport);
13242            }
13243        }.start();
13244    }
13245
13246    /**
13247     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13248     * @param app object of the crashing app, null for the system server
13249     * @param tag reported by the caller
13250     * @param system whether this wtf is coming from the system
13251     * @param crashInfo describing the context of the error
13252     * @return true if the process should exit immediately (WTF is fatal)
13253     */
13254    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13255            final ApplicationErrorReport.CrashInfo crashInfo) {
13256        final int callingUid = Binder.getCallingUid();
13257        final int callingPid = Binder.getCallingPid();
13258
13259        if (system) {
13260            // If this is coming from the system, we could very well have low-level
13261            // system locks held, so we want to do this all asynchronously.  And we
13262            // never want this to become fatal, so there is that too.
13263            mHandler.post(new Runnable() {
13264                @Override public void run() {
13265                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13266                }
13267            });
13268            return false;
13269        }
13270
13271        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13272                crashInfo);
13273
13274        if (r != null && r.pid != Process.myPid() &&
13275                Settings.Global.getInt(mContext.getContentResolver(),
13276                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13277            mAppErrors.crashApplication(r, crashInfo);
13278            return true;
13279        } else {
13280            return false;
13281        }
13282    }
13283
13284    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13285            final ApplicationErrorReport.CrashInfo crashInfo) {
13286        final ProcessRecord r = findAppProcess(app, "WTF");
13287        final String processName = app == null ? "system_server"
13288                : (r == null ? "unknown" : r.processName);
13289
13290        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13291                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13292
13293        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13294
13295        return r;
13296    }
13297
13298    /**
13299     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13300     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13301     */
13302    private ProcessRecord findAppProcess(IBinder app, String reason) {
13303        if (app == null) {
13304            return null;
13305        }
13306
13307        synchronized (this) {
13308            final int NP = mProcessNames.getMap().size();
13309            for (int ip=0; ip<NP; ip++) {
13310                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13311                final int NA = apps.size();
13312                for (int ia=0; ia<NA; ia++) {
13313                    ProcessRecord p = apps.valueAt(ia);
13314                    if (p.thread != null && p.thread.asBinder() == app) {
13315                        return p;
13316                    }
13317                }
13318            }
13319
13320            Slog.w(TAG, "Can't find mystery application for " + reason
13321                    + " from pid=" + Binder.getCallingPid()
13322                    + " uid=" + Binder.getCallingUid() + ": " + app);
13323            return null;
13324        }
13325    }
13326
13327    /**
13328     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13329     * to append various headers to the dropbox log text.
13330     */
13331    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13332            StringBuilder sb) {
13333        // Watchdog thread ends up invoking this function (with
13334        // a null ProcessRecord) to add the stack file to dropbox.
13335        // Do not acquire a lock on this (am) in such cases, as it
13336        // could cause a potential deadlock, if and when watchdog
13337        // is invoked due to unavailability of lock on am and it
13338        // would prevent watchdog from killing system_server.
13339        if (process == null) {
13340            sb.append("Process: ").append(processName).append("\n");
13341            return;
13342        }
13343        // Note: ProcessRecord 'process' is guarded by the service
13344        // instance.  (notably process.pkgList, which could otherwise change
13345        // concurrently during execution of this method)
13346        synchronized (this) {
13347            sb.append("Process: ").append(processName).append("\n");
13348            int flags = process.info.flags;
13349            IPackageManager pm = AppGlobals.getPackageManager();
13350            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13351            for (int ip=0; ip<process.pkgList.size(); ip++) {
13352                String pkg = process.pkgList.keyAt(ip);
13353                sb.append("Package: ").append(pkg);
13354                try {
13355                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13356                    if (pi != null) {
13357                        sb.append(" v").append(pi.versionCode);
13358                        if (pi.versionName != null) {
13359                            sb.append(" (").append(pi.versionName).append(")");
13360                        }
13361                    }
13362                } catch (RemoteException e) {
13363                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13364                }
13365                sb.append("\n");
13366            }
13367        }
13368    }
13369
13370    private static String processClass(ProcessRecord process) {
13371        if (process == null || process.pid == MY_PID) {
13372            return "system_server";
13373        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13374            return "system_app";
13375        } else {
13376            return "data_app";
13377        }
13378    }
13379
13380    private volatile long mWtfClusterStart;
13381    private volatile int mWtfClusterCount;
13382
13383    /**
13384     * Write a description of an error (crash, WTF, ANR) to the drop box.
13385     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13386     * @param process which caused the error, null means the system server
13387     * @param activity which triggered the error, null if unknown
13388     * @param parent activity related to the error, null if unknown
13389     * @param subject line related to the error, null if absent
13390     * @param report in long form describing the error, null if absent
13391     * @param logFile to include in the report, null if none
13392     * @param crashInfo giving an application stack trace, null if absent
13393     */
13394    public void addErrorToDropBox(String eventType,
13395            ProcessRecord process, String processName, ActivityRecord activity,
13396            ActivityRecord parent, String subject,
13397            final String report, final File logFile,
13398            final ApplicationErrorReport.CrashInfo crashInfo) {
13399        // NOTE -- this must never acquire the ActivityManagerService lock,
13400        // otherwise the watchdog may be prevented from resetting the system.
13401
13402        final String dropboxTag = processClass(process) + "_" + eventType;
13403        final DropBoxManager dbox = (DropBoxManager)
13404                mContext.getSystemService(Context.DROPBOX_SERVICE);
13405
13406        // Exit early if the dropbox isn't configured to accept this report type.
13407        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13408
13409        // Rate-limit how often we're willing to do the heavy lifting below to
13410        // collect and record logs; currently 5 logs per 10 second period.
13411        final long now = SystemClock.elapsedRealtime();
13412        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13413            mWtfClusterStart = now;
13414            mWtfClusterCount = 1;
13415        } else {
13416            if (mWtfClusterCount++ >= 5) return;
13417        }
13418
13419        final StringBuilder sb = new StringBuilder(1024);
13420        appendDropBoxProcessHeaders(process, processName, sb);
13421        if (process != null) {
13422            sb.append("Foreground: ")
13423                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13424                    .append("\n");
13425        }
13426        if (activity != null) {
13427            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13428        }
13429        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13430            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13431        }
13432        if (parent != null && parent != activity) {
13433            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13434        }
13435        if (subject != null) {
13436            sb.append("Subject: ").append(subject).append("\n");
13437        }
13438        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13439        if (Debug.isDebuggerConnected()) {
13440            sb.append("Debugger: Connected\n");
13441        }
13442        sb.append("\n");
13443
13444        // Do the rest in a worker thread to avoid blocking the caller on I/O
13445        // (After this point, we shouldn't access AMS internal data structures.)
13446        Thread worker = new Thread("Error dump: " + dropboxTag) {
13447            @Override
13448            public void run() {
13449                if (report != null) {
13450                    sb.append(report);
13451                }
13452                if (logFile != null) {
13453                    try {
13454                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13455                                    "\n\n[[TRUNCATED]]"));
13456                    } catch (IOException e) {
13457                        Slog.e(TAG, "Error reading " + logFile, e);
13458                    }
13459                }
13460                if (crashInfo != null && crashInfo.stackTrace != null) {
13461                    sb.append(crashInfo.stackTrace);
13462                }
13463
13464                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13465                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13466                if (lines > 0) {
13467                    sb.append("\n");
13468
13469                    // Merge several logcat streams, and take the last N lines
13470                    InputStreamReader input = null;
13471                    try {
13472                        java.lang.Process logcat = new ProcessBuilder(
13473                                "/system/bin/timeout", "-k", "15s", "10s",
13474                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13475                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13476                                        .redirectErrorStream(true).start();
13477
13478                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13479                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13480                        input = new InputStreamReader(logcat.getInputStream());
13481
13482                        int num;
13483                        char[] buf = new char[8192];
13484                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13485                    } catch (IOException e) {
13486                        Slog.e(TAG, "Error running logcat", e);
13487                    } finally {
13488                        if (input != null) try { input.close(); } catch (IOException e) {}
13489                    }
13490                }
13491
13492                dbox.addText(dropboxTag, sb.toString());
13493            }
13494        };
13495
13496        if (process == null) {
13497            // If process is null, we are being called from some internal code
13498            // and may be about to die -- run this synchronously.
13499            worker.run();
13500        } else {
13501            worker.start();
13502        }
13503    }
13504
13505    @Override
13506    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13507        enforceNotIsolatedCaller("getProcessesInErrorState");
13508        // assume our apps are happy - lazy create the list
13509        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13510
13511        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13512                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13513        int userId = UserHandle.getUserId(Binder.getCallingUid());
13514
13515        synchronized (this) {
13516
13517            // iterate across all processes
13518            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13519                ProcessRecord app = mLruProcesses.get(i);
13520                if (!allUsers && app.userId != userId) {
13521                    continue;
13522                }
13523                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13524                    // This one's in trouble, so we'll generate a report for it
13525                    // crashes are higher priority (in case there's a crash *and* an anr)
13526                    ActivityManager.ProcessErrorStateInfo report = null;
13527                    if (app.crashing) {
13528                        report = app.crashingReport;
13529                    } else if (app.notResponding) {
13530                        report = app.notRespondingReport;
13531                    }
13532
13533                    if (report != null) {
13534                        if (errList == null) {
13535                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13536                        }
13537                        errList.add(report);
13538                    } else {
13539                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13540                                " crashing = " + app.crashing +
13541                                " notResponding = " + app.notResponding);
13542                    }
13543                }
13544            }
13545        }
13546
13547        return errList;
13548    }
13549
13550    static int procStateToImportance(int procState, int memAdj,
13551            ActivityManager.RunningAppProcessInfo currApp) {
13552        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13553        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13554            currApp.lru = memAdj;
13555        } else {
13556            currApp.lru = 0;
13557        }
13558        return imp;
13559    }
13560
13561    private void fillInProcMemInfo(ProcessRecord app,
13562            ActivityManager.RunningAppProcessInfo outInfo) {
13563        outInfo.pid = app.pid;
13564        outInfo.uid = app.info.uid;
13565        if (mHeavyWeightProcess == app) {
13566            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13567        }
13568        if (app.persistent) {
13569            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13570        }
13571        if (app.activities.size() > 0) {
13572            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13573        }
13574        outInfo.lastTrimLevel = app.trimMemoryLevel;
13575        int adj = app.curAdj;
13576        int procState = app.curProcState;
13577        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13578        outInfo.importanceReasonCode = app.adjTypeCode;
13579        outInfo.processState = app.curProcState;
13580    }
13581
13582    @Override
13583    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13584        enforceNotIsolatedCaller("getRunningAppProcesses");
13585
13586        final int callingUid = Binder.getCallingUid();
13587
13588        // Lazy instantiation of list
13589        List<ActivityManager.RunningAppProcessInfo> runList = null;
13590        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13591                callingUid) == PackageManager.PERMISSION_GRANTED;
13592        final int userId = UserHandle.getUserId(callingUid);
13593        final boolean allUids = isGetTasksAllowed(
13594                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13595
13596        synchronized (this) {
13597            // Iterate across all processes
13598            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13599                ProcessRecord app = mLruProcesses.get(i);
13600                if ((!allUsers && app.userId != userId)
13601                        || (!allUids && app.uid != callingUid)) {
13602                    continue;
13603                }
13604                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13605                    // Generate process state info for running application
13606                    ActivityManager.RunningAppProcessInfo currApp =
13607                        new ActivityManager.RunningAppProcessInfo(app.processName,
13608                                app.pid, app.getPackageList());
13609                    fillInProcMemInfo(app, currApp);
13610                    if (app.adjSource instanceof ProcessRecord) {
13611                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13612                        currApp.importanceReasonImportance =
13613                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13614                                        app.adjSourceProcState);
13615                    } else if (app.adjSource instanceof ActivityRecord) {
13616                        ActivityRecord r = (ActivityRecord)app.adjSource;
13617                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13618                    }
13619                    if (app.adjTarget instanceof ComponentName) {
13620                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13621                    }
13622                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13623                    //        + " lru=" + currApp.lru);
13624                    if (runList == null) {
13625                        runList = new ArrayList<>();
13626                    }
13627                    runList.add(currApp);
13628                }
13629            }
13630        }
13631        return runList;
13632    }
13633
13634    @Override
13635    public List<ApplicationInfo> getRunningExternalApplications() {
13636        enforceNotIsolatedCaller("getRunningExternalApplications");
13637        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13638        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13639        if (runningApps != null && runningApps.size() > 0) {
13640            Set<String> extList = new HashSet<String>();
13641            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13642                if (app.pkgList != null) {
13643                    for (String pkg : app.pkgList) {
13644                        extList.add(pkg);
13645                    }
13646                }
13647            }
13648            IPackageManager pm = AppGlobals.getPackageManager();
13649            for (String pkg : extList) {
13650                try {
13651                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13652                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13653                        retList.add(info);
13654                    }
13655                } catch (RemoteException e) {
13656                }
13657            }
13658        }
13659        return retList;
13660    }
13661
13662    @Override
13663    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13664        enforceNotIsolatedCaller("getMyMemoryState");
13665        synchronized (this) {
13666            ProcessRecord proc;
13667            synchronized (mPidsSelfLocked) {
13668                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13669            }
13670            fillInProcMemInfo(proc, outInfo);
13671        }
13672    }
13673
13674    @Override
13675    public int getMemoryTrimLevel() {
13676        enforceNotIsolatedCaller("getMyMemoryState");
13677        synchronized (this) {
13678            return mLastMemoryLevel;
13679        }
13680    }
13681
13682    @Override
13683    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13684            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13685        (new ActivityManagerShellCommand(this, false)).exec(
13686                this, in, out, err, args, resultReceiver);
13687    }
13688
13689    @Override
13690    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13691        if (checkCallingPermission(android.Manifest.permission.DUMP)
13692                != PackageManager.PERMISSION_GRANTED) {
13693            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13694                    + Binder.getCallingPid()
13695                    + ", uid=" + Binder.getCallingUid()
13696                    + " without permission "
13697                    + android.Manifest.permission.DUMP);
13698            return;
13699        }
13700
13701        boolean dumpAll = false;
13702        boolean dumpClient = false;
13703        String dumpPackage = null;
13704
13705        int opti = 0;
13706        while (opti < args.length) {
13707            String opt = args[opti];
13708            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13709                break;
13710            }
13711            opti++;
13712            if ("-a".equals(opt)) {
13713                dumpAll = true;
13714            } else if ("-c".equals(opt)) {
13715                dumpClient = true;
13716            } else if ("-p".equals(opt)) {
13717                if (opti < args.length) {
13718                    dumpPackage = args[opti];
13719                    opti++;
13720                } else {
13721                    pw.println("Error: -p option requires package argument");
13722                    return;
13723                }
13724                dumpClient = true;
13725            } else if ("-h".equals(opt)) {
13726                ActivityManagerShellCommand.dumpHelp(pw, true);
13727                return;
13728            } else {
13729                pw.println("Unknown argument: " + opt + "; use -h for help");
13730            }
13731        }
13732
13733        long origId = Binder.clearCallingIdentity();
13734        boolean more = false;
13735        // Is the caller requesting to dump a particular piece of data?
13736        if (opti < args.length) {
13737            String cmd = args[opti];
13738            opti++;
13739            if ("activities".equals(cmd) || "a".equals(cmd)) {
13740                synchronized (this) {
13741                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13742                }
13743            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13744                synchronized (this) {
13745                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13746                }
13747            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13748                String[] newArgs;
13749                String name;
13750                if (opti >= args.length) {
13751                    name = null;
13752                    newArgs = EMPTY_STRING_ARRAY;
13753                } else {
13754                    dumpPackage = args[opti];
13755                    opti++;
13756                    newArgs = new String[args.length - opti];
13757                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13758                            args.length - opti);
13759                }
13760                synchronized (this) {
13761                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13762                }
13763            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13764                String[] newArgs;
13765                String name;
13766                if (opti >= args.length) {
13767                    name = null;
13768                    newArgs = EMPTY_STRING_ARRAY;
13769                } else {
13770                    dumpPackage = args[opti];
13771                    opti++;
13772                    newArgs = new String[args.length - opti];
13773                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13774                            args.length - opti);
13775                }
13776                synchronized (this) {
13777                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13778                }
13779            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13780                String[] newArgs;
13781                String name;
13782                if (opti >= args.length) {
13783                    name = null;
13784                    newArgs = EMPTY_STRING_ARRAY;
13785                } else {
13786                    dumpPackage = args[opti];
13787                    opti++;
13788                    newArgs = new String[args.length - opti];
13789                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13790                            args.length - opti);
13791                }
13792                synchronized (this) {
13793                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13794                }
13795            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13796                synchronized (this) {
13797                    dumpOomLocked(fd, pw, args, opti, true);
13798                }
13799            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13800                synchronized (this) {
13801                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13802                }
13803            } else if ("provider".equals(cmd)) {
13804                String[] newArgs;
13805                String name;
13806                if (opti >= args.length) {
13807                    name = null;
13808                    newArgs = EMPTY_STRING_ARRAY;
13809                } else {
13810                    name = args[opti];
13811                    opti++;
13812                    newArgs = new String[args.length - opti];
13813                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13814                }
13815                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13816                    pw.println("No providers match: " + name);
13817                    pw.println("Use -h for help.");
13818                }
13819            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13820                synchronized (this) {
13821                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13822                }
13823            } else if ("service".equals(cmd)) {
13824                String[] newArgs;
13825                String name;
13826                if (opti >= args.length) {
13827                    name = null;
13828                    newArgs = EMPTY_STRING_ARRAY;
13829                } else {
13830                    name = args[opti];
13831                    opti++;
13832                    newArgs = new String[args.length - opti];
13833                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13834                            args.length - opti);
13835                }
13836                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13837                    pw.println("No services match: " + name);
13838                    pw.println("Use -h for help.");
13839                }
13840            } else if ("package".equals(cmd)) {
13841                String[] newArgs;
13842                if (opti >= args.length) {
13843                    pw.println("package: no package name specified");
13844                    pw.println("Use -h for help.");
13845                } else {
13846                    dumpPackage = args[opti];
13847                    opti++;
13848                    newArgs = new String[args.length - opti];
13849                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13850                            args.length - opti);
13851                    args = newArgs;
13852                    opti = 0;
13853                    more = true;
13854                }
13855            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13856                synchronized (this) {
13857                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13858                }
13859            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13860                if (dumpClient) {
13861                    ActiveServices.ServiceDumper dumper;
13862                    synchronized (this) {
13863                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13864                                dumpPackage);
13865                    }
13866                    dumper.dumpWithClient();
13867                } else {
13868                    synchronized (this) {
13869                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13870                                dumpPackage).dumpLocked();
13871                    }
13872                }
13873            } else if ("locks".equals(cmd)) {
13874                LockGuard.dump(fd, pw, args);
13875            } else {
13876                // Dumping a single activity?
13877                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13878                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13879                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13880                    if (res < 0) {
13881                        pw.println("Bad activity command, or no activities match: " + cmd);
13882                        pw.println("Use -h for help.");
13883                    }
13884                }
13885            }
13886            if (!more) {
13887                Binder.restoreCallingIdentity(origId);
13888                return;
13889            }
13890        }
13891
13892        // No piece of data specified, dump everything.
13893        if (dumpClient) {
13894            ActiveServices.ServiceDumper sdumper;
13895            synchronized (this) {
13896                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13897                pw.println();
13898                if (dumpAll) {
13899                    pw.println("-------------------------------------------------------------------------------");
13900                }
13901                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13902                pw.println();
13903                if (dumpAll) {
13904                    pw.println("-------------------------------------------------------------------------------");
13905                }
13906                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13907                pw.println();
13908                if (dumpAll) {
13909                    pw.println("-------------------------------------------------------------------------------");
13910                }
13911                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13912                pw.println();
13913                if (dumpAll) {
13914                    pw.println("-------------------------------------------------------------------------------");
13915                }
13916                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13917                        dumpPackage);
13918            }
13919            sdumper.dumpWithClient();
13920            pw.println();
13921            synchronized (this) {
13922                if (dumpAll) {
13923                    pw.println("-------------------------------------------------------------------------------");
13924                }
13925                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13926                pw.println();
13927                if (dumpAll) {
13928                    pw.println("-------------------------------------------------------------------------------");
13929                }
13930                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13931                if (mAssociations.size() > 0) {
13932                    pw.println();
13933                    if (dumpAll) {
13934                        pw.println("-------------------------------------------------------------------------------");
13935                    }
13936                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13937                }
13938                pw.println();
13939                if (dumpAll) {
13940                    pw.println("-------------------------------------------------------------------------------");
13941                }
13942                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13943            }
13944
13945        } else {
13946            synchronized (this) {
13947                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13948                pw.println();
13949                if (dumpAll) {
13950                    pw.println("-------------------------------------------------------------------------------");
13951                }
13952                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13953                pw.println();
13954                if (dumpAll) {
13955                    pw.println("-------------------------------------------------------------------------------");
13956                }
13957                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13958                pw.println();
13959                if (dumpAll) {
13960                    pw.println("-------------------------------------------------------------------------------");
13961                }
13962                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13963                pw.println();
13964                if (dumpAll) {
13965                    pw.println("-------------------------------------------------------------------------------");
13966                }
13967                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13968                        .dumpLocked();
13969                pw.println();
13970                if (dumpAll) {
13971                    pw.println("-------------------------------------------------------------------------------");
13972                }
13973                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13974                pw.println();
13975                if (dumpAll) {
13976                    pw.println("-------------------------------------------------------------------------------");
13977                }
13978                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13979                if (mAssociations.size() > 0) {
13980                    pw.println();
13981                    if (dumpAll) {
13982                        pw.println("-------------------------------------------------------------------------------");
13983                    }
13984                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13985                }
13986                pw.println();
13987                if (dumpAll) {
13988                    pw.println("-------------------------------------------------------------------------------");
13989                }
13990                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13991            }
13992        }
13993        Binder.restoreCallingIdentity(origId);
13994    }
13995
13996    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13997            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13998        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13999
14000        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14001                dumpPackage);
14002        boolean needSep = printedAnything;
14003
14004        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14005                dumpPackage, needSep, "  mFocusedActivity: ");
14006        if (printed) {
14007            printedAnything = true;
14008            needSep = false;
14009        }
14010
14011        if (dumpPackage == null) {
14012            if (needSep) {
14013                pw.println();
14014            }
14015            needSep = true;
14016            printedAnything = true;
14017            mStackSupervisor.dump(pw, "  ");
14018        }
14019
14020        if (!printedAnything) {
14021            pw.println("  (nothing)");
14022        }
14023    }
14024
14025    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14026            int opti, boolean dumpAll, String dumpPackage) {
14027        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14028
14029        boolean printedAnything = false;
14030
14031        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14032            boolean printedHeader = false;
14033
14034            final int N = mRecentTasks.size();
14035            for (int i=0; i<N; i++) {
14036                TaskRecord tr = mRecentTasks.get(i);
14037                if (dumpPackage != null) {
14038                    if (tr.realActivity == null ||
14039                            !dumpPackage.equals(tr.realActivity)) {
14040                        continue;
14041                    }
14042                }
14043                if (!printedHeader) {
14044                    pw.println("  Recent tasks:");
14045                    printedHeader = true;
14046                    printedAnything = true;
14047                }
14048                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14049                        pw.println(tr);
14050                if (dumpAll) {
14051                    mRecentTasks.get(i).dump(pw, "    ");
14052                }
14053            }
14054        }
14055
14056        if (!printedAnything) {
14057            pw.println("  (nothing)");
14058        }
14059    }
14060
14061    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14062            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14063        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14064
14065        int dumpUid = 0;
14066        if (dumpPackage != null) {
14067            IPackageManager pm = AppGlobals.getPackageManager();
14068            try {
14069                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14070            } catch (RemoteException e) {
14071            }
14072        }
14073
14074        boolean printedAnything = false;
14075
14076        final long now = SystemClock.uptimeMillis();
14077
14078        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14079            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14080                    = mAssociations.valueAt(i1);
14081            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14082                SparseArray<ArrayMap<String, Association>> sourceUids
14083                        = targetComponents.valueAt(i2);
14084                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14085                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14086                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14087                        Association ass = sourceProcesses.valueAt(i4);
14088                        if (dumpPackage != null) {
14089                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14090                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14091                                continue;
14092                            }
14093                        }
14094                        printedAnything = true;
14095                        pw.print("  ");
14096                        pw.print(ass.mTargetProcess);
14097                        pw.print("/");
14098                        UserHandle.formatUid(pw, ass.mTargetUid);
14099                        pw.print(" <- ");
14100                        pw.print(ass.mSourceProcess);
14101                        pw.print("/");
14102                        UserHandle.formatUid(pw, ass.mSourceUid);
14103                        pw.println();
14104                        pw.print("    via ");
14105                        pw.print(ass.mTargetComponent.flattenToShortString());
14106                        pw.println();
14107                        pw.print("    ");
14108                        long dur = ass.mTime;
14109                        if (ass.mNesting > 0) {
14110                            dur += now - ass.mStartTime;
14111                        }
14112                        TimeUtils.formatDuration(dur, pw);
14113                        pw.print(" (");
14114                        pw.print(ass.mCount);
14115                        pw.print(" times)");
14116                        pw.print("  ");
14117                        for (int i=0; i<ass.mStateTimes.length; i++) {
14118                            long amt = ass.mStateTimes[i];
14119                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14120                                amt += now - ass.mLastStateUptime;
14121                            }
14122                            if (amt != 0) {
14123                                pw.print(" ");
14124                                pw.print(ProcessList.makeProcStateString(
14125                                            i + ActivityManager.MIN_PROCESS_STATE));
14126                                pw.print("=");
14127                                TimeUtils.formatDuration(amt, pw);
14128                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14129                                    pw.print("*");
14130                                }
14131                            }
14132                        }
14133                        pw.println();
14134                        if (ass.mNesting > 0) {
14135                            pw.print("    Currently active: ");
14136                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14137                            pw.println();
14138                        }
14139                    }
14140                }
14141            }
14142
14143        }
14144
14145        if (!printedAnything) {
14146            pw.println("  (nothing)");
14147        }
14148    }
14149
14150    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14151            String header, boolean needSep) {
14152        boolean printed = false;
14153        int whichAppId = -1;
14154        if (dumpPackage != null) {
14155            try {
14156                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14157                        dumpPackage, 0);
14158                whichAppId = UserHandle.getAppId(info.uid);
14159            } catch (NameNotFoundException e) {
14160                e.printStackTrace();
14161            }
14162        }
14163        for (int i=0; i<uids.size(); i++) {
14164            UidRecord uidRec = uids.valueAt(i);
14165            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14166                continue;
14167            }
14168            if (!printed) {
14169                printed = true;
14170                if (needSep) {
14171                    pw.println();
14172                }
14173                pw.print("  ");
14174                pw.println(header);
14175                needSep = true;
14176            }
14177            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14178            pw.print(": "); pw.println(uidRec);
14179        }
14180        return printed;
14181    }
14182
14183    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14184            int opti, boolean dumpAll, String dumpPackage) {
14185        boolean needSep = false;
14186        boolean printedAnything = false;
14187        int numPers = 0;
14188
14189        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14190
14191        if (dumpAll) {
14192            final int NP = mProcessNames.getMap().size();
14193            for (int ip=0; ip<NP; ip++) {
14194                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14195                final int NA = procs.size();
14196                for (int ia=0; ia<NA; ia++) {
14197                    ProcessRecord r = procs.valueAt(ia);
14198                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14199                        continue;
14200                    }
14201                    if (!needSep) {
14202                        pw.println("  All known processes:");
14203                        needSep = true;
14204                        printedAnything = true;
14205                    }
14206                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14207                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14208                        pw.print(" "); pw.println(r);
14209                    r.dump(pw, "    ");
14210                    if (r.persistent) {
14211                        numPers++;
14212                    }
14213                }
14214            }
14215        }
14216
14217        if (mIsolatedProcesses.size() > 0) {
14218            boolean printed = false;
14219            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14220                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14221                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14222                    continue;
14223                }
14224                if (!printed) {
14225                    if (needSep) {
14226                        pw.println();
14227                    }
14228                    pw.println("  Isolated process list (sorted by uid):");
14229                    printedAnything = true;
14230                    printed = true;
14231                    needSep = true;
14232                }
14233                pw.println(String.format("%sIsolated #%2d: %s",
14234                        "    ", i, r.toString()));
14235            }
14236        }
14237
14238        if (mActiveUids.size() > 0) {
14239            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14240                printedAnything = needSep = true;
14241            }
14242        }
14243        if (mValidateUids.size() > 0) {
14244            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14245                printedAnything = needSep = true;
14246            }
14247        }
14248
14249        if (mLruProcesses.size() > 0) {
14250            if (needSep) {
14251                pw.println();
14252            }
14253            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14254                    pw.print(" total, non-act at ");
14255                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14256                    pw.print(", non-svc at ");
14257                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14258                    pw.println("):");
14259            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14260            needSep = true;
14261            printedAnything = true;
14262        }
14263
14264        if (dumpAll || dumpPackage != null) {
14265            synchronized (mPidsSelfLocked) {
14266                boolean printed = false;
14267                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14268                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14269                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14270                        continue;
14271                    }
14272                    if (!printed) {
14273                        if (needSep) pw.println();
14274                        needSep = true;
14275                        pw.println("  PID mappings:");
14276                        printed = true;
14277                        printedAnything = true;
14278                    }
14279                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14280                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14281                }
14282            }
14283        }
14284
14285        if (mForegroundProcesses.size() > 0) {
14286            synchronized (mPidsSelfLocked) {
14287                boolean printed = false;
14288                for (int i=0; i<mForegroundProcesses.size(); i++) {
14289                    ProcessRecord r = mPidsSelfLocked.get(
14290                            mForegroundProcesses.valueAt(i).pid);
14291                    if (dumpPackage != null && (r == null
14292                            || !r.pkgList.containsKey(dumpPackage))) {
14293                        continue;
14294                    }
14295                    if (!printed) {
14296                        if (needSep) pw.println();
14297                        needSep = true;
14298                        pw.println("  Foreground Processes:");
14299                        printed = true;
14300                        printedAnything = true;
14301                    }
14302                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14303                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14304                }
14305            }
14306        }
14307
14308        if (mPersistentStartingProcesses.size() > 0) {
14309            if (needSep) pw.println();
14310            needSep = true;
14311            printedAnything = true;
14312            pw.println("  Persisent processes that are starting:");
14313            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14314                    "Starting Norm", "Restarting PERS", dumpPackage);
14315        }
14316
14317        if (mRemovedProcesses.size() > 0) {
14318            if (needSep) pw.println();
14319            needSep = true;
14320            printedAnything = true;
14321            pw.println("  Processes that are being removed:");
14322            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14323                    "Removed Norm", "Removed PERS", dumpPackage);
14324        }
14325
14326        if (mProcessesOnHold.size() > 0) {
14327            if (needSep) pw.println();
14328            needSep = true;
14329            printedAnything = true;
14330            pw.println("  Processes that are on old until the system is ready:");
14331            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14332                    "OnHold Norm", "OnHold PERS", dumpPackage);
14333        }
14334
14335        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14336
14337        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14338        if (needSep) {
14339            printedAnything = true;
14340        }
14341
14342        if (dumpPackage == null) {
14343            pw.println();
14344            needSep = false;
14345            mUserController.dump(pw, dumpAll);
14346        }
14347        if (mHomeProcess != null && (dumpPackage == null
14348                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14349            if (needSep) {
14350                pw.println();
14351                needSep = false;
14352            }
14353            pw.println("  mHomeProcess: " + mHomeProcess);
14354        }
14355        if (mPreviousProcess != null && (dumpPackage == null
14356                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14357            if (needSep) {
14358                pw.println();
14359                needSep = false;
14360            }
14361            pw.println("  mPreviousProcess: " + mPreviousProcess);
14362        }
14363        if (dumpAll) {
14364            StringBuilder sb = new StringBuilder(128);
14365            sb.append("  mPreviousProcessVisibleTime: ");
14366            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14367            pw.println(sb);
14368        }
14369        if (mHeavyWeightProcess != null && (dumpPackage == null
14370                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14371            if (needSep) {
14372                pw.println();
14373                needSep = false;
14374            }
14375            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14376        }
14377        if (dumpPackage == null) {
14378            pw.println("  mConfiguration: " + mConfiguration);
14379        }
14380        if (dumpAll) {
14381            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14382            if (mCompatModePackages.getPackages().size() > 0) {
14383                boolean printed = false;
14384                for (Map.Entry<String, Integer> entry
14385                        : mCompatModePackages.getPackages().entrySet()) {
14386                    String pkg = entry.getKey();
14387                    int mode = entry.getValue();
14388                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14389                        continue;
14390                    }
14391                    if (!printed) {
14392                        pw.println("  mScreenCompatPackages:");
14393                        printed = true;
14394                    }
14395                    pw.print("    "); pw.print(pkg); pw.print(": ");
14396                            pw.print(mode); pw.println();
14397                }
14398            }
14399        }
14400        if (dumpPackage == null) {
14401            pw.println("  mWakefulness="
14402                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14403            pw.println("  mSleepTokens=" + mSleepTokens);
14404            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14405                    + lockScreenShownToString());
14406            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14407            if (mRunningVoice != null) {
14408                pw.println("  mRunningVoice=" + mRunningVoice);
14409                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14410            }
14411        }
14412        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14413                || mOrigWaitForDebugger) {
14414            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14415                    || dumpPackage.equals(mOrigDebugApp)) {
14416                if (needSep) {
14417                    pw.println();
14418                    needSep = false;
14419                }
14420                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14421                        + " mDebugTransient=" + mDebugTransient
14422                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14423            }
14424        }
14425        if (mCurAppTimeTracker != null) {
14426            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14427        }
14428        if (mMemWatchProcesses.getMap().size() > 0) {
14429            pw.println("  Mem watch processes:");
14430            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14431                    = mMemWatchProcesses.getMap();
14432            for (int i=0; i<procs.size(); i++) {
14433                final String proc = procs.keyAt(i);
14434                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14435                for (int j=0; j<uids.size(); j++) {
14436                    if (needSep) {
14437                        pw.println();
14438                        needSep = false;
14439                    }
14440                    StringBuilder sb = new StringBuilder();
14441                    sb.append("    ").append(proc).append('/');
14442                    UserHandle.formatUid(sb, uids.keyAt(j));
14443                    Pair<Long, String> val = uids.valueAt(j);
14444                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14445                    if (val.second != null) {
14446                        sb.append(", report to ").append(val.second);
14447                    }
14448                    pw.println(sb.toString());
14449                }
14450            }
14451            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14452            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14453            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14454                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14455        }
14456        if (mTrackAllocationApp != null) {
14457            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14458                if (needSep) {
14459                    pw.println();
14460                    needSep = false;
14461                }
14462                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14463            }
14464        }
14465        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14466                || mProfileFd != null) {
14467            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14468                if (needSep) {
14469                    pw.println();
14470                    needSep = false;
14471                }
14472                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14473                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14474                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14475                        + mAutoStopProfiler);
14476                pw.println("  mProfileType=" + mProfileType);
14477            }
14478        }
14479        if (mNativeDebuggingApp != null) {
14480            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14481                if (needSep) {
14482                    pw.println();
14483                    needSep = false;
14484                }
14485                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14486            }
14487        }
14488        if (dumpPackage == null) {
14489            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14490                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14491                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14492            }
14493            if (mController != null) {
14494                pw.println("  mController=" + mController
14495                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14496            }
14497            if (dumpAll) {
14498                pw.println("  Total persistent processes: " + numPers);
14499                pw.println("  mProcessesReady=" + mProcessesReady
14500                        + " mSystemReady=" + mSystemReady
14501                        + " mBooted=" + mBooted
14502                        + " mFactoryTest=" + mFactoryTest);
14503                pw.println("  mBooting=" + mBooting
14504                        + " mCallFinishBooting=" + mCallFinishBooting
14505                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14506                pw.print("  mLastPowerCheckRealtime=");
14507                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14508                        pw.println("");
14509                pw.print("  mLastPowerCheckUptime=");
14510                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14511                        pw.println("");
14512                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14513                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14514                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14515                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14516                        + " (" + mLruProcesses.size() + " total)"
14517                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14518                        + " mNumServiceProcs=" + mNumServiceProcs
14519                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14520                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14521                        + " mLastMemoryLevel=" + mLastMemoryLevel
14522                        + " mLastNumProcesses=" + mLastNumProcesses);
14523                long now = SystemClock.uptimeMillis();
14524                pw.print("  mLastIdleTime=");
14525                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14526                        pw.print(" mLowRamSinceLastIdle=");
14527                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14528                        pw.println();
14529            }
14530        }
14531
14532        if (!printedAnything) {
14533            pw.println("  (nothing)");
14534        }
14535    }
14536
14537    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14538            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14539        if (mProcessesToGc.size() > 0) {
14540            boolean printed = false;
14541            long now = SystemClock.uptimeMillis();
14542            for (int i=0; i<mProcessesToGc.size(); i++) {
14543                ProcessRecord proc = mProcessesToGc.get(i);
14544                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14545                    continue;
14546                }
14547                if (!printed) {
14548                    if (needSep) pw.println();
14549                    needSep = true;
14550                    pw.println("  Processes that are waiting to GC:");
14551                    printed = true;
14552                }
14553                pw.print("    Process "); pw.println(proc);
14554                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14555                        pw.print(", last gced=");
14556                        pw.print(now-proc.lastRequestedGc);
14557                        pw.print(" ms ago, last lowMem=");
14558                        pw.print(now-proc.lastLowMemory);
14559                        pw.println(" ms ago");
14560
14561            }
14562        }
14563        return needSep;
14564    }
14565
14566    void printOomLevel(PrintWriter pw, String name, int adj) {
14567        pw.print("    ");
14568        if (adj >= 0) {
14569            pw.print(' ');
14570            if (adj < 10) pw.print(' ');
14571        } else {
14572            if (adj > -10) pw.print(' ');
14573        }
14574        pw.print(adj);
14575        pw.print(": ");
14576        pw.print(name);
14577        pw.print(" (");
14578        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14579        pw.println(")");
14580    }
14581
14582    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14583            int opti, boolean dumpAll) {
14584        boolean needSep = false;
14585
14586        if (mLruProcesses.size() > 0) {
14587            if (needSep) pw.println();
14588            needSep = true;
14589            pw.println("  OOM levels:");
14590            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14591            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14592            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14593            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14594            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14595            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14596            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14597            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14598            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14599            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14600            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14601            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14602            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14603            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14604
14605            if (needSep) pw.println();
14606            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14607                    pw.print(" total, non-act at ");
14608                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14609                    pw.print(", non-svc at ");
14610                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14611                    pw.println("):");
14612            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14613            needSep = true;
14614        }
14615
14616        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14617
14618        pw.println();
14619        pw.println("  mHomeProcess: " + mHomeProcess);
14620        pw.println("  mPreviousProcess: " + mPreviousProcess);
14621        if (mHeavyWeightProcess != null) {
14622            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14623        }
14624
14625        return true;
14626    }
14627
14628    /**
14629     * There are three ways to call this:
14630     *  - no provider specified: dump all the providers
14631     *  - a flattened component name that matched an existing provider was specified as the
14632     *    first arg: dump that one provider
14633     *  - the first arg isn't the flattened component name of an existing provider:
14634     *    dump all providers whose component contains the first arg as a substring
14635     */
14636    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14637            int opti, boolean dumpAll) {
14638        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14639    }
14640
14641    static class ItemMatcher {
14642        ArrayList<ComponentName> components;
14643        ArrayList<String> strings;
14644        ArrayList<Integer> objects;
14645        boolean all;
14646
14647        ItemMatcher() {
14648            all = true;
14649        }
14650
14651        void build(String name) {
14652            ComponentName componentName = ComponentName.unflattenFromString(name);
14653            if (componentName != null) {
14654                if (components == null) {
14655                    components = new ArrayList<ComponentName>();
14656                }
14657                components.add(componentName);
14658                all = false;
14659            } else {
14660                int objectId = 0;
14661                // Not a '/' separated full component name; maybe an object ID?
14662                try {
14663                    objectId = Integer.parseInt(name, 16);
14664                    if (objects == null) {
14665                        objects = new ArrayList<Integer>();
14666                    }
14667                    objects.add(objectId);
14668                    all = false;
14669                } catch (RuntimeException e) {
14670                    // Not an integer; just do string match.
14671                    if (strings == null) {
14672                        strings = new ArrayList<String>();
14673                    }
14674                    strings.add(name);
14675                    all = false;
14676                }
14677            }
14678        }
14679
14680        int build(String[] args, int opti) {
14681            for (; opti<args.length; opti++) {
14682                String name = args[opti];
14683                if ("--".equals(name)) {
14684                    return opti+1;
14685                }
14686                build(name);
14687            }
14688            return opti;
14689        }
14690
14691        boolean match(Object object, ComponentName comp) {
14692            if (all) {
14693                return true;
14694            }
14695            if (components != null) {
14696                for (int i=0; i<components.size(); i++) {
14697                    if (components.get(i).equals(comp)) {
14698                        return true;
14699                    }
14700                }
14701            }
14702            if (objects != null) {
14703                for (int i=0; i<objects.size(); i++) {
14704                    if (System.identityHashCode(object) == objects.get(i)) {
14705                        return true;
14706                    }
14707                }
14708            }
14709            if (strings != null) {
14710                String flat = comp.flattenToString();
14711                for (int i=0; i<strings.size(); i++) {
14712                    if (flat.contains(strings.get(i))) {
14713                        return true;
14714                    }
14715                }
14716            }
14717            return false;
14718        }
14719    }
14720
14721    /**
14722     * There are three things that cmd can be:
14723     *  - a flattened component name that matches an existing activity
14724     *  - the cmd arg isn't the flattened component name of an existing activity:
14725     *    dump all activity whose component contains the cmd as a substring
14726     *  - A hex number of the ActivityRecord object instance.
14727     */
14728    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14729            int opti, boolean dumpAll) {
14730        ArrayList<ActivityRecord> activities;
14731
14732        synchronized (this) {
14733            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14734        }
14735
14736        if (activities.size() <= 0) {
14737            return false;
14738        }
14739
14740        String[] newArgs = new String[args.length - opti];
14741        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14742
14743        TaskRecord lastTask = null;
14744        boolean needSep = false;
14745        for (int i=activities.size()-1; i>=0; i--) {
14746            ActivityRecord r = activities.get(i);
14747            if (needSep) {
14748                pw.println();
14749            }
14750            needSep = true;
14751            synchronized (this) {
14752                if (lastTask != r.task) {
14753                    lastTask = r.task;
14754                    pw.print("TASK "); pw.print(lastTask.affinity);
14755                            pw.print(" id="); pw.println(lastTask.taskId);
14756                    if (dumpAll) {
14757                        lastTask.dump(pw, "  ");
14758                    }
14759                }
14760            }
14761            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14762        }
14763        return true;
14764    }
14765
14766    /**
14767     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14768     * there is a thread associated with the activity.
14769     */
14770    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14771            final ActivityRecord r, String[] args, boolean dumpAll) {
14772        String innerPrefix = prefix + "  ";
14773        synchronized (this) {
14774            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14775                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14776                    pw.print(" pid=");
14777                    if (r.app != null) pw.println(r.app.pid);
14778                    else pw.println("(not running)");
14779            if (dumpAll) {
14780                r.dump(pw, innerPrefix);
14781            }
14782        }
14783        if (r.app != null && r.app.thread != null) {
14784            // flush anything that is already in the PrintWriter since the thread is going
14785            // to write to the file descriptor directly
14786            pw.flush();
14787            try {
14788                TransferPipe tp = new TransferPipe();
14789                try {
14790                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14791                            r.appToken, innerPrefix, args);
14792                    tp.go(fd);
14793                } finally {
14794                    tp.kill();
14795                }
14796            } catch (IOException e) {
14797                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14798            } catch (RemoteException e) {
14799                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14800            }
14801        }
14802    }
14803
14804    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14805            int opti, boolean dumpAll, String dumpPackage) {
14806        boolean needSep = false;
14807        boolean onlyHistory = false;
14808        boolean printedAnything = false;
14809
14810        if ("history".equals(dumpPackage)) {
14811            if (opti < args.length && "-s".equals(args[opti])) {
14812                dumpAll = false;
14813            }
14814            onlyHistory = true;
14815            dumpPackage = null;
14816        }
14817
14818        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14819        if (!onlyHistory && dumpAll) {
14820            if (mRegisteredReceivers.size() > 0) {
14821                boolean printed = false;
14822                Iterator it = mRegisteredReceivers.values().iterator();
14823                while (it.hasNext()) {
14824                    ReceiverList r = (ReceiverList)it.next();
14825                    if (dumpPackage != null && (r.app == null ||
14826                            !dumpPackage.equals(r.app.info.packageName))) {
14827                        continue;
14828                    }
14829                    if (!printed) {
14830                        pw.println("  Registered Receivers:");
14831                        needSep = true;
14832                        printed = true;
14833                        printedAnything = true;
14834                    }
14835                    pw.print("  * "); pw.println(r);
14836                    r.dump(pw, "    ");
14837                }
14838            }
14839
14840            if (mReceiverResolver.dump(pw, needSep ?
14841                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14842                    "    ", dumpPackage, false, false)) {
14843                needSep = true;
14844                printedAnything = true;
14845            }
14846        }
14847
14848        for (BroadcastQueue q : mBroadcastQueues) {
14849            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14850            printedAnything |= needSep;
14851        }
14852
14853        needSep = true;
14854
14855        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14856            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14857                if (needSep) {
14858                    pw.println();
14859                }
14860                needSep = true;
14861                printedAnything = true;
14862                pw.print("  Sticky broadcasts for user ");
14863                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14864                StringBuilder sb = new StringBuilder(128);
14865                for (Map.Entry<String, ArrayList<Intent>> ent
14866                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14867                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14868                    if (dumpAll) {
14869                        pw.println(":");
14870                        ArrayList<Intent> intents = ent.getValue();
14871                        final int N = intents.size();
14872                        for (int i=0; i<N; i++) {
14873                            sb.setLength(0);
14874                            sb.append("    Intent: ");
14875                            intents.get(i).toShortString(sb, false, true, false, false);
14876                            pw.println(sb.toString());
14877                            Bundle bundle = intents.get(i).getExtras();
14878                            if (bundle != null) {
14879                                pw.print("      ");
14880                                pw.println(bundle.toString());
14881                            }
14882                        }
14883                    } else {
14884                        pw.println("");
14885                    }
14886                }
14887            }
14888        }
14889
14890        if (!onlyHistory && dumpAll) {
14891            pw.println();
14892            for (BroadcastQueue queue : mBroadcastQueues) {
14893                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14894                        + queue.mBroadcastsScheduled);
14895            }
14896            pw.println("  mHandler:");
14897            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14898            needSep = true;
14899            printedAnything = true;
14900        }
14901
14902        if (!printedAnything) {
14903            pw.println("  (nothing)");
14904        }
14905    }
14906
14907    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14908            int opti, boolean dumpAll, String dumpPackage) {
14909        boolean needSep;
14910        boolean printedAnything = false;
14911
14912        ItemMatcher matcher = new ItemMatcher();
14913        matcher.build(args, opti);
14914
14915        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14916
14917        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14918        printedAnything |= needSep;
14919
14920        if (mLaunchingProviders.size() > 0) {
14921            boolean printed = false;
14922            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14923                ContentProviderRecord r = mLaunchingProviders.get(i);
14924                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14925                    continue;
14926                }
14927                if (!printed) {
14928                    if (needSep) pw.println();
14929                    needSep = true;
14930                    pw.println("  Launching content providers:");
14931                    printed = true;
14932                    printedAnything = true;
14933                }
14934                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14935                        pw.println(r);
14936            }
14937        }
14938
14939        if (!printedAnything) {
14940            pw.println("  (nothing)");
14941        }
14942    }
14943
14944    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14945            int opti, boolean dumpAll, String dumpPackage) {
14946        boolean needSep = false;
14947        boolean printedAnything = false;
14948
14949        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14950
14951        if (mGrantedUriPermissions.size() > 0) {
14952            boolean printed = false;
14953            int dumpUid = -2;
14954            if (dumpPackage != null) {
14955                try {
14956                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14957                            MATCH_UNINSTALLED_PACKAGES, 0);
14958                } catch (NameNotFoundException e) {
14959                    dumpUid = -1;
14960                }
14961            }
14962            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14963                int uid = mGrantedUriPermissions.keyAt(i);
14964                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14965                    continue;
14966                }
14967                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14968                if (!printed) {
14969                    if (needSep) pw.println();
14970                    needSep = true;
14971                    pw.println("  Granted Uri Permissions:");
14972                    printed = true;
14973                    printedAnything = true;
14974                }
14975                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14976                for (UriPermission perm : perms.values()) {
14977                    pw.print("    "); pw.println(perm);
14978                    if (dumpAll) {
14979                        perm.dump(pw, "      ");
14980                    }
14981                }
14982            }
14983        }
14984
14985        if (!printedAnything) {
14986            pw.println("  (nothing)");
14987        }
14988    }
14989
14990    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14991            int opti, boolean dumpAll, String dumpPackage) {
14992        boolean printed = false;
14993
14994        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14995
14996        if (mIntentSenderRecords.size() > 0) {
14997            Iterator<WeakReference<PendingIntentRecord>> it
14998                    = mIntentSenderRecords.values().iterator();
14999            while (it.hasNext()) {
15000                WeakReference<PendingIntentRecord> ref = it.next();
15001                PendingIntentRecord rec = ref != null ? ref.get(): null;
15002                if (dumpPackage != null && (rec == null
15003                        || !dumpPackage.equals(rec.key.packageName))) {
15004                    continue;
15005                }
15006                printed = true;
15007                if (rec != null) {
15008                    pw.print("  * "); pw.println(rec);
15009                    if (dumpAll) {
15010                        rec.dump(pw, "    ");
15011                    }
15012                } else {
15013                    pw.print("  * "); pw.println(ref);
15014                }
15015            }
15016        }
15017
15018        if (!printed) {
15019            pw.println("  (nothing)");
15020        }
15021    }
15022
15023    private static final int dumpProcessList(PrintWriter pw,
15024            ActivityManagerService service, List list,
15025            String prefix, String normalLabel, String persistentLabel,
15026            String dumpPackage) {
15027        int numPers = 0;
15028        final int N = list.size()-1;
15029        for (int i=N; i>=0; i--) {
15030            ProcessRecord r = (ProcessRecord)list.get(i);
15031            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15032                continue;
15033            }
15034            pw.println(String.format("%s%s #%2d: %s",
15035                    prefix, (r.persistent ? persistentLabel : normalLabel),
15036                    i, r.toString()));
15037            if (r.persistent) {
15038                numPers++;
15039            }
15040        }
15041        return numPers;
15042    }
15043
15044    private static final boolean dumpProcessOomList(PrintWriter pw,
15045            ActivityManagerService service, List<ProcessRecord> origList,
15046            String prefix, String normalLabel, String persistentLabel,
15047            boolean inclDetails, String dumpPackage) {
15048
15049        ArrayList<Pair<ProcessRecord, Integer>> list
15050                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15051        for (int i=0; i<origList.size(); i++) {
15052            ProcessRecord r = origList.get(i);
15053            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15054                continue;
15055            }
15056            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15057        }
15058
15059        if (list.size() <= 0) {
15060            return false;
15061        }
15062
15063        Comparator<Pair<ProcessRecord, Integer>> comparator
15064                = new Comparator<Pair<ProcessRecord, Integer>>() {
15065            @Override
15066            public int compare(Pair<ProcessRecord, Integer> object1,
15067                    Pair<ProcessRecord, Integer> object2) {
15068                if (object1.first.setAdj != object2.first.setAdj) {
15069                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15070                }
15071                if (object1.first.setProcState != object2.first.setProcState) {
15072                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15073                }
15074                if (object1.second.intValue() != object2.second.intValue()) {
15075                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15076                }
15077                return 0;
15078            }
15079        };
15080
15081        Collections.sort(list, comparator);
15082
15083        final long curRealtime = SystemClock.elapsedRealtime();
15084        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15085        final long curUptime = SystemClock.uptimeMillis();
15086        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15087
15088        for (int i=list.size()-1; i>=0; i--) {
15089            ProcessRecord r = list.get(i).first;
15090            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15091            char schedGroup;
15092            switch (r.setSchedGroup) {
15093                case ProcessList.SCHED_GROUP_BACKGROUND:
15094                    schedGroup = 'B';
15095                    break;
15096                case ProcessList.SCHED_GROUP_DEFAULT:
15097                    schedGroup = 'F';
15098                    break;
15099                case ProcessList.SCHED_GROUP_TOP_APP:
15100                    schedGroup = 'T';
15101                    break;
15102                default:
15103                    schedGroup = '?';
15104                    break;
15105            }
15106            char foreground;
15107            if (r.foregroundActivities) {
15108                foreground = 'A';
15109            } else if (r.foregroundServices) {
15110                foreground = 'S';
15111            } else {
15112                foreground = ' ';
15113            }
15114            String procState = ProcessList.makeProcStateString(r.curProcState);
15115            pw.print(prefix);
15116            pw.print(r.persistent ? persistentLabel : normalLabel);
15117            pw.print(" #");
15118            int num = (origList.size()-1)-list.get(i).second;
15119            if (num < 10) pw.print(' ');
15120            pw.print(num);
15121            pw.print(": ");
15122            pw.print(oomAdj);
15123            pw.print(' ');
15124            pw.print(schedGroup);
15125            pw.print('/');
15126            pw.print(foreground);
15127            pw.print('/');
15128            pw.print(procState);
15129            pw.print(" trm:");
15130            if (r.trimMemoryLevel < 10) pw.print(' ');
15131            pw.print(r.trimMemoryLevel);
15132            pw.print(' ');
15133            pw.print(r.toShortString());
15134            pw.print(" (");
15135            pw.print(r.adjType);
15136            pw.println(')');
15137            if (r.adjSource != null || r.adjTarget != null) {
15138                pw.print(prefix);
15139                pw.print("    ");
15140                if (r.adjTarget instanceof ComponentName) {
15141                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15142                } else if (r.adjTarget != null) {
15143                    pw.print(r.adjTarget.toString());
15144                } else {
15145                    pw.print("{null}");
15146                }
15147                pw.print("<=");
15148                if (r.adjSource instanceof ProcessRecord) {
15149                    pw.print("Proc{");
15150                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15151                    pw.println("}");
15152                } else if (r.adjSource != null) {
15153                    pw.println(r.adjSource.toString());
15154                } else {
15155                    pw.println("{null}");
15156                }
15157            }
15158            if (inclDetails) {
15159                pw.print(prefix);
15160                pw.print("    ");
15161                pw.print("oom: max="); pw.print(r.maxAdj);
15162                pw.print(" curRaw="); pw.print(r.curRawAdj);
15163                pw.print(" setRaw="); pw.print(r.setRawAdj);
15164                pw.print(" cur="); pw.print(r.curAdj);
15165                pw.print(" set="); pw.println(r.setAdj);
15166                pw.print(prefix);
15167                pw.print("    ");
15168                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15169                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15170                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15171                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15172                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15173                pw.println();
15174                pw.print(prefix);
15175                pw.print("    ");
15176                pw.print("cached="); pw.print(r.cached);
15177                pw.print(" empty="); pw.print(r.empty);
15178                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15179
15180                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15181                    if (r.lastWakeTime != 0) {
15182                        long wtime;
15183                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15184                        synchronized (stats) {
15185                            wtime = stats.getProcessWakeTime(r.info.uid,
15186                                    r.pid, curRealtime);
15187                        }
15188                        long timeUsed = wtime - r.lastWakeTime;
15189                        pw.print(prefix);
15190                        pw.print("    ");
15191                        pw.print("keep awake over ");
15192                        TimeUtils.formatDuration(realtimeSince, pw);
15193                        pw.print(" used ");
15194                        TimeUtils.formatDuration(timeUsed, pw);
15195                        pw.print(" (");
15196                        pw.print((timeUsed*100)/realtimeSince);
15197                        pw.println("%)");
15198                    }
15199                    if (r.lastCpuTime != 0) {
15200                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15201                        pw.print(prefix);
15202                        pw.print("    ");
15203                        pw.print("run cpu over ");
15204                        TimeUtils.formatDuration(uptimeSince, pw);
15205                        pw.print(" used ");
15206                        TimeUtils.formatDuration(timeUsed, pw);
15207                        pw.print(" (");
15208                        pw.print((timeUsed*100)/uptimeSince);
15209                        pw.println("%)");
15210                    }
15211                }
15212            }
15213        }
15214        return true;
15215    }
15216
15217    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15218            String[] args) {
15219        ArrayList<ProcessRecord> procs;
15220        synchronized (this) {
15221            if (args != null && args.length > start
15222                    && args[start].charAt(0) != '-') {
15223                procs = new ArrayList<ProcessRecord>();
15224                int pid = -1;
15225                try {
15226                    pid = Integer.parseInt(args[start]);
15227                } catch (NumberFormatException e) {
15228                }
15229                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15230                    ProcessRecord proc = mLruProcesses.get(i);
15231                    if (proc.pid == pid) {
15232                        procs.add(proc);
15233                    } else if (allPkgs && proc.pkgList != null
15234                            && proc.pkgList.containsKey(args[start])) {
15235                        procs.add(proc);
15236                    } else if (proc.processName.equals(args[start])) {
15237                        procs.add(proc);
15238                    }
15239                }
15240                if (procs.size() <= 0) {
15241                    return null;
15242                }
15243            } else {
15244                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15245            }
15246        }
15247        return procs;
15248    }
15249
15250    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15251            PrintWriter pw, String[] args) {
15252        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15253        if (procs == null) {
15254            pw.println("No process found for: " + args[0]);
15255            return;
15256        }
15257
15258        long uptime = SystemClock.uptimeMillis();
15259        long realtime = SystemClock.elapsedRealtime();
15260        pw.println("Applications Graphics Acceleration Info:");
15261        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15262
15263        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15264            ProcessRecord r = procs.get(i);
15265            if (r.thread != null) {
15266                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15267                pw.flush();
15268                try {
15269                    TransferPipe tp = new TransferPipe();
15270                    try {
15271                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15272                        tp.go(fd);
15273                    } finally {
15274                        tp.kill();
15275                    }
15276                } catch (IOException e) {
15277                    pw.println("Failure while dumping the app: " + r);
15278                    pw.flush();
15279                } catch (RemoteException e) {
15280                    pw.println("Got a RemoteException while dumping the app " + r);
15281                    pw.flush();
15282                }
15283            }
15284        }
15285    }
15286
15287    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15288        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15289        if (procs == null) {
15290            pw.println("No process found for: " + args[0]);
15291            return;
15292        }
15293
15294        pw.println("Applications Database Info:");
15295
15296        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15297            ProcessRecord r = procs.get(i);
15298            if (r.thread != null) {
15299                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15300                pw.flush();
15301                try {
15302                    TransferPipe tp = new TransferPipe();
15303                    try {
15304                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15305                        tp.go(fd);
15306                    } finally {
15307                        tp.kill();
15308                    }
15309                } catch (IOException e) {
15310                    pw.println("Failure while dumping the app: " + r);
15311                    pw.flush();
15312                } catch (RemoteException e) {
15313                    pw.println("Got a RemoteException while dumping the app " + r);
15314                    pw.flush();
15315                }
15316            }
15317        }
15318    }
15319
15320    final static class MemItem {
15321        final boolean isProc;
15322        final String label;
15323        final String shortLabel;
15324        final long pss;
15325        final long swapPss;
15326        final int id;
15327        final boolean hasActivities;
15328        ArrayList<MemItem> subitems;
15329
15330        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15331                boolean _hasActivities) {
15332            isProc = true;
15333            label = _label;
15334            shortLabel = _shortLabel;
15335            pss = _pss;
15336            swapPss = _swapPss;
15337            id = _id;
15338            hasActivities = _hasActivities;
15339        }
15340
15341        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15342            isProc = false;
15343            label = _label;
15344            shortLabel = _shortLabel;
15345            pss = _pss;
15346            swapPss = _swapPss;
15347            id = _id;
15348            hasActivities = false;
15349        }
15350    }
15351
15352    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15353            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15354        if (sort && !isCompact) {
15355            Collections.sort(items, new Comparator<MemItem>() {
15356                @Override
15357                public int compare(MemItem lhs, MemItem rhs) {
15358                    if (lhs.pss < rhs.pss) {
15359                        return 1;
15360                    } else if (lhs.pss > rhs.pss) {
15361                        return -1;
15362                    }
15363                    return 0;
15364                }
15365            });
15366        }
15367
15368        for (int i=0; i<items.size(); i++) {
15369            MemItem mi = items.get(i);
15370            if (!isCompact) {
15371                if (dumpSwapPss) {
15372                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15373                            mi.label, stringifyKBSize(mi.swapPss));
15374                } else {
15375                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15376                }
15377            } else if (mi.isProc) {
15378                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15379                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15380                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15381                pw.println(mi.hasActivities ? ",a" : ",e");
15382            } else {
15383                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15384                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15385            }
15386            if (mi.subitems != null) {
15387                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15388                        true, isCompact, dumpSwapPss);
15389            }
15390        }
15391    }
15392
15393    // These are in KB.
15394    static final long[] DUMP_MEM_BUCKETS = new long[] {
15395        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15396        120*1024, 160*1024, 200*1024,
15397        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15398        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15399    };
15400
15401    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15402            boolean stackLike) {
15403        int start = label.lastIndexOf('.');
15404        if (start >= 0) start++;
15405        else start = 0;
15406        int end = label.length();
15407        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15408            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15409                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15410                out.append(bucket);
15411                out.append(stackLike ? "MB." : "MB ");
15412                out.append(label, start, end);
15413                return;
15414            }
15415        }
15416        out.append(memKB/1024);
15417        out.append(stackLike ? "MB." : "MB ");
15418        out.append(label, start, end);
15419    }
15420
15421    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15422            ProcessList.NATIVE_ADJ,
15423            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15424            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15425            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15426            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15427            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15428            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15429    };
15430    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15431            "Native",
15432            "System", "Persistent", "Persistent Service", "Foreground",
15433            "Visible", "Perceptible",
15434            "Heavy Weight", "Backup",
15435            "A Services", "Home",
15436            "Previous", "B Services", "Cached"
15437    };
15438    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15439            "native",
15440            "sys", "pers", "persvc", "fore",
15441            "vis", "percept",
15442            "heavy", "backup",
15443            "servicea", "home",
15444            "prev", "serviceb", "cached"
15445    };
15446
15447    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15448            long realtime, boolean isCheckinRequest, boolean isCompact) {
15449        if (isCompact) {
15450            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15451        }
15452        if (isCheckinRequest || isCompact) {
15453            // short checkin version
15454            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15455        } else {
15456            pw.println("Applications Memory Usage (in Kilobytes):");
15457            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15458        }
15459    }
15460
15461    private static final int KSM_SHARED = 0;
15462    private static final int KSM_SHARING = 1;
15463    private static final int KSM_UNSHARED = 2;
15464    private static final int KSM_VOLATILE = 3;
15465
15466    private final long[] getKsmInfo() {
15467        long[] longOut = new long[4];
15468        final int[] SINGLE_LONG_FORMAT = new int[] {
15469            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15470        };
15471        long[] longTmp = new long[1];
15472        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15473                SINGLE_LONG_FORMAT, null, longTmp, null);
15474        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15475        longTmp[0] = 0;
15476        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15477                SINGLE_LONG_FORMAT, null, longTmp, null);
15478        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15479        longTmp[0] = 0;
15480        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15481                SINGLE_LONG_FORMAT, null, longTmp, null);
15482        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15483        longTmp[0] = 0;
15484        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15485                SINGLE_LONG_FORMAT, null, longTmp, null);
15486        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15487        return longOut;
15488    }
15489
15490    private static String stringifySize(long size, int order) {
15491        Locale locale = Locale.US;
15492        switch (order) {
15493            case 1:
15494                return String.format(locale, "%,13d", size);
15495            case 1024:
15496                return String.format(locale, "%,9dK", size / 1024);
15497            case 1024 * 1024:
15498                return String.format(locale, "%,5dM", size / 1024 / 1024);
15499            case 1024 * 1024 * 1024:
15500                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15501            default:
15502                throw new IllegalArgumentException("Invalid size order");
15503        }
15504    }
15505
15506    private static String stringifyKBSize(long size) {
15507        return stringifySize(size * 1024, 1024);
15508    }
15509
15510    // Update this version number in case you change the 'compact' format
15511    private static final int MEMINFO_COMPACT_VERSION = 1;
15512
15513    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15514            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15515        boolean dumpDetails = false;
15516        boolean dumpFullDetails = false;
15517        boolean dumpDalvik = false;
15518        boolean dumpSummaryOnly = false;
15519        boolean dumpUnreachable = false;
15520        boolean oomOnly = false;
15521        boolean isCompact = false;
15522        boolean localOnly = false;
15523        boolean packages = false;
15524        boolean isCheckinRequest = false;
15525        boolean dumpSwapPss = false;
15526
15527        int opti = 0;
15528        while (opti < args.length) {
15529            String opt = args[opti];
15530            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15531                break;
15532            }
15533            opti++;
15534            if ("-a".equals(opt)) {
15535                dumpDetails = true;
15536                dumpFullDetails = true;
15537                dumpDalvik = true;
15538                dumpSwapPss = true;
15539            } else if ("-d".equals(opt)) {
15540                dumpDalvik = true;
15541            } else if ("-c".equals(opt)) {
15542                isCompact = true;
15543            } else if ("-s".equals(opt)) {
15544                dumpDetails = true;
15545                dumpSummaryOnly = true;
15546            } else if ("-S".equals(opt)) {
15547                dumpSwapPss = true;
15548            } else if ("--unreachable".equals(opt)) {
15549                dumpUnreachable = true;
15550            } else if ("--oom".equals(opt)) {
15551                oomOnly = true;
15552            } else if ("--local".equals(opt)) {
15553                localOnly = true;
15554            } else if ("--package".equals(opt)) {
15555                packages = true;
15556            } else if ("--checkin".equals(opt)) {
15557                isCheckinRequest = true;
15558
15559            } else if ("-h".equals(opt)) {
15560                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15561                pw.println("  -a: include all available information for each process.");
15562                pw.println("  -d: include dalvik details.");
15563                pw.println("  -c: dump in a compact machine-parseable representation.");
15564                pw.println("  -s: dump only summary of application memory usage.");
15565                pw.println("  -S: dump also SwapPss.");
15566                pw.println("  --oom: only show processes organized by oom adj.");
15567                pw.println("  --local: only collect details locally, don't call process.");
15568                pw.println("  --package: interpret process arg as package, dumping all");
15569                pw.println("             processes that have loaded that package.");
15570                pw.println("  --checkin: dump data for a checkin");
15571                pw.println("If [process] is specified it can be the name or ");
15572                pw.println("pid of a specific process to dump.");
15573                return;
15574            } else {
15575                pw.println("Unknown argument: " + opt + "; use -h for help");
15576            }
15577        }
15578
15579        long uptime = SystemClock.uptimeMillis();
15580        long realtime = SystemClock.elapsedRealtime();
15581        final long[] tmpLong = new long[1];
15582
15583        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15584        if (procs == null) {
15585            // No Java processes.  Maybe they want to print a native process.
15586            if (args != null && args.length > opti
15587                    && args[opti].charAt(0) != '-') {
15588                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15589                        = new ArrayList<ProcessCpuTracker.Stats>();
15590                updateCpuStatsNow();
15591                int findPid = -1;
15592                try {
15593                    findPid = Integer.parseInt(args[opti]);
15594                } catch (NumberFormatException e) {
15595                }
15596                synchronized (mProcessCpuTracker) {
15597                    final int N = mProcessCpuTracker.countStats();
15598                    for (int i=0; i<N; i++) {
15599                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15600                        if (st.pid == findPid || (st.baseName != null
15601                                && st.baseName.equals(args[opti]))) {
15602                            nativeProcs.add(st);
15603                        }
15604                    }
15605                }
15606                if (nativeProcs.size() > 0) {
15607                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15608                            isCompact);
15609                    Debug.MemoryInfo mi = null;
15610                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15611                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15612                        final int pid = r.pid;
15613                        if (!isCheckinRequest && dumpDetails) {
15614                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15615                        }
15616                        if (mi == null) {
15617                            mi = new Debug.MemoryInfo();
15618                        }
15619                        if (dumpDetails || (!brief && !oomOnly)) {
15620                            Debug.getMemoryInfo(pid, mi);
15621                        } else {
15622                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15623                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15624                        }
15625                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15626                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15627                        if (isCheckinRequest) {
15628                            pw.println();
15629                        }
15630                    }
15631                    return;
15632                }
15633            }
15634            pw.println("No process found for: " + args[opti]);
15635            return;
15636        }
15637
15638        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15639            dumpDetails = true;
15640        }
15641
15642        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15643
15644        String[] innerArgs = new String[args.length-opti];
15645        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15646
15647        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15648        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15649        long nativePss = 0;
15650        long nativeSwapPss = 0;
15651        long dalvikPss = 0;
15652        long dalvikSwapPss = 0;
15653        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15654                EmptyArray.LONG;
15655        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15656                EmptyArray.LONG;
15657        long otherPss = 0;
15658        long otherSwapPss = 0;
15659        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15660        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15661
15662        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15663        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15664        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15665                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15666
15667        long totalPss = 0;
15668        long totalSwapPss = 0;
15669        long cachedPss = 0;
15670        long cachedSwapPss = 0;
15671        boolean hasSwapPss = false;
15672
15673        Debug.MemoryInfo mi = null;
15674        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15675            final ProcessRecord r = procs.get(i);
15676            final IApplicationThread thread;
15677            final int pid;
15678            final int oomAdj;
15679            final boolean hasActivities;
15680            synchronized (this) {
15681                thread = r.thread;
15682                pid = r.pid;
15683                oomAdj = r.getSetAdjWithServices();
15684                hasActivities = r.activities.size() > 0;
15685            }
15686            if (thread != null) {
15687                if (!isCheckinRequest && dumpDetails) {
15688                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15689                }
15690                if (mi == null) {
15691                    mi = new Debug.MemoryInfo();
15692                }
15693                if (dumpDetails || (!brief && !oomOnly)) {
15694                    Debug.getMemoryInfo(pid, mi);
15695                    hasSwapPss = mi.hasSwappedOutPss;
15696                } else {
15697                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15698                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15699                }
15700                if (dumpDetails) {
15701                    if (localOnly) {
15702                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15703                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15704                        if (isCheckinRequest) {
15705                            pw.println();
15706                        }
15707                    } else {
15708                        try {
15709                            pw.flush();
15710                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15711                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15712                        } catch (RemoteException e) {
15713                            if (!isCheckinRequest) {
15714                                pw.println("Got RemoteException!");
15715                                pw.flush();
15716                            }
15717                        }
15718                    }
15719                }
15720
15721                final long myTotalPss = mi.getTotalPss();
15722                final long myTotalUss = mi.getTotalUss();
15723                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15724
15725                synchronized (this) {
15726                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15727                        // Record this for posterity if the process has been stable.
15728                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15729                    }
15730                }
15731
15732                if (!isCheckinRequest && mi != null) {
15733                    totalPss += myTotalPss;
15734                    totalSwapPss += myTotalSwapPss;
15735                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15736                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15737                            myTotalSwapPss, pid, hasActivities);
15738                    procMems.add(pssItem);
15739                    procMemsMap.put(pid, pssItem);
15740
15741                    nativePss += mi.nativePss;
15742                    nativeSwapPss += mi.nativeSwappedOutPss;
15743                    dalvikPss += mi.dalvikPss;
15744                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15745                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15746                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15747                        dalvikSubitemSwapPss[j] +=
15748                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15749                    }
15750                    otherPss += mi.otherPss;
15751                    otherSwapPss += mi.otherSwappedOutPss;
15752                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15753                        long mem = mi.getOtherPss(j);
15754                        miscPss[j] += mem;
15755                        otherPss -= mem;
15756                        mem = mi.getOtherSwappedOutPss(j);
15757                        miscSwapPss[j] += mem;
15758                        otherSwapPss -= mem;
15759                    }
15760
15761                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15762                        cachedPss += myTotalPss;
15763                        cachedSwapPss += myTotalSwapPss;
15764                    }
15765
15766                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15767                        if (oomIndex == (oomPss.length - 1)
15768                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15769                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15770                            oomPss[oomIndex] += myTotalPss;
15771                            oomSwapPss[oomIndex] += myTotalSwapPss;
15772                            if (oomProcs[oomIndex] == null) {
15773                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15774                            }
15775                            oomProcs[oomIndex].add(pssItem);
15776                            break;
15777                        }
15778                    }
15779                }
15780            }
15781        }
15782
15783        long nativeProcTotalPss = 0;
15784
15785        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15786            // If we are showing aggregations, also look for native processes to
15787            // include so that our aggregations are more accurate.
15788            updateCpuStatsNow();
15789            mi = null;
15790            synchronized (mProcessCpuTracker) {
15791                final int N = mProcessCpuTracker.countStats();
15792                for (int i=0; i<N; i++) {
15793                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15794                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15795                        if (mi == null) {
15796                            mi = new Debug.MemoryInfo();
15797                        }
15798                        if (!brief && !oomOnly) {
15799                            Debug.getMemoryInfo(st.pid, mi);
15800                        } else {
15801                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15802                            mi.nativePrivateDirty = (int)tmpLong[0];
15803                        }
15804
15805                        final long myTotalPss = mi.getTotalPss();
15806                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15807                        totalPss += myTotalPss;
15808                        nativeProcTotalPss += myTotalPss;
15809
15810                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15811                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15812                        procMems.add(pssItem);
15813
15814                        nativePss += mi.nativePss;
15815                        nativeSwapPss += mi.nativeSwappedOutPss;
15816                        dalvikPss += mi.dalvikPss;
15817                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15818                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15819                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15820                            dalvikSubitemSwapPss[j] +=
15821                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15822                        }
15823                        otherPss += mi.otherPss;
15824                        otherSwapPss += mi.otherSwappedOutPss;
15825                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15826                            long mem = mi.getOtherPss(j);
15827                            miscPss[j] += mem;
15828                            otherPss -= mem;
15829                            mem = mi.getOtherSwappedOutPss(j);
15830                            miscSwapPss[j] += mem;
15831                            otherSwapPss -= mem;
15832                        }
15833                        oomPss[0] += myTotalPss;
15834                        oomSwapPss[0] += myTotalSwapPss;
15835                        if (oomProcs[0] == null) {
15836                            oomProcs[0] = new ArrayList<MemItem>();
15837                        }
15838                        oomProcs[0].add(pssItem);
15839                    }
15840                }
15841            }
15842
15843            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15844
15845            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15846            final MemItem dalvikItem =
15847                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15848            if (dalvikSubitemPss.length > 0) {
15849                dalvikItem.subitems = new ArrayList<MemItem>();
15850                for (int j=0; j<dalvikSubitemPss.length; j++) {
15851                    final String name = Debug.MemoryInfo.getOtherLabel(
15852                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15853                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15854                                    dalvikSubitemSwapPss[j], j));
15855                }
15856            }
15857            catMems.add(dalvikItem);
15858            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15859            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15860                String label = Debug.MemoryInfo.getOtherLabel(j);
15861                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15862            }
15863
15864            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15865            for (int j=0; j<oomPss.length; j++) {
15866                if (oomPss[j] != 0) {
15867                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15868                            : DUMP_MEM_OOM_LABEL[j];
15869                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15870                            DUMP_MEM_OOM_ADJ[j]);
15871                    item.subitems = oomProcs[j];
15872                    oomMems.add(item);
15873                }
15874            }
15875
15876            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15877            if (!brief && !oomOnly && !isCompact) {
15878                pw.println();
15879                pw.println("Total PSS by process:");
15880                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15881                pw.println();
15882            }
15883            if (!isCompact) {
15884                pw.println("Total PSS by OOM adjustment:");
15885            }
15886            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15887            if (!brief && !oomOnly) {
15888                PrintWriter out = categoryPw != null ? categoryPw : pw;
15889                if (!isCompact) {
15890                    out.println();
15891                    out.println("Total PSS by category:");
15892                }
15893                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15894            }
15895            if (!isCompact) {
15896                pw.println();
15897            }
15898            MemInfoReader memInfo = new MemInfoReader();
15899            memInfo.readMemInfo();
15900            if (nativeProcTotalPss > 0) {
15901                synchronized (this) {
15902                    final long cachedKb = memInfo.getCachedSizeKb();
15903                    final long freeKb = memInfo.getFreeSizeKb();
15904                    final long zramKb = memInfo.getZramTotalSizeKb();
15905                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15906                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15907                            kernelKb*1024, nativeProcTotalPss*1024);
15908                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15909                            nativeProcTotalPss);
15910                }
15911            }
15912            if (!brief) {
15913                if (!isCompact) {
15914                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15915                    pw.print(" (status ");
15916                    switch (mLastMemoryLevel) {
15917                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15918                            pw.println("normal)");
15919                            break;
15920                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15921                            pw.println("moderate)");
15922                            break;
15923                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15924                            pw.println("low)");
15925                            break;
15926                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15927                            pw.println("critical)");
15928                            break;
15929                        default:
15930                            pw.print(mLastMemoryLevel);
15931                            pw.println(")");
15932                            break;
15933                    }
15934                    pw.print(" Free RAM: ");
15935                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15936                            + memInfo.getFreeSizeKb()));
15937                    pw.print(" (");
15938                    pw.print(stringifyKBSize(cachedPss));
15939                    pw.print(" cached pss + ");
15940                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15941                    pw.print(" cached kernel + ");
15942                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15943                    pw.println(" free)");
15944                } else {
15945                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15946                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15947                            + memInfo.getFreeSizeKb()); pw.print(",");
15948                    pw.println(totalPss - cachedPss);
15949                }
15950            }
15951            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15952                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15953                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15954            if (!isCompact) {
15955                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15956                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15957                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15958                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15959                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15960            } else {
15961                pw.print("lostram,"); pw.println(lostRAM);
15962            }
15963            if (!brief) {
15964                if (memInfo.getZramTotalSizeKb() != 0) {
15965                    if (!isCompact) {
15966                        pw.print("     ZRAM: ");
15967                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15968                                pw.print(" physical used for ");
15969                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15970                                        - memInfo.getSwapFreeSizeKb()));
15971                                pw.print(" in swap (");
15972                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15973                                pw.println(" total swap)");
15974                    } else {
15975                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15976                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15977                                pw.println(memInfo.getSwapFreeSizeKb());
15978                    }
15979                }
15980                final long[] ksm = getKsmInfo();
15981                if (!isCompact) {
15982                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15983                            || ksm[KSM_VOLATILE] != 0) {
15984                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15985                                pw.print(" saved from shared ");
15986                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15987                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15988                                pw.print(" unshared; ");
15989                                pw.print(stringifyKBSize(
15990                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15991                    }
15992                    pw.print("   Tuning: ");
15993                    pw.print(ActivityManager.staticGetMemoryClass());
15994                    pw.print(" (large ");
15995                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15996                    pw.print("), oom ");
15997                    pw.print(stringifySize(
15998                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15999                    pw.print(", restore limit ");
16000                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16001                    if (ActivityManager.isLowRamDeviceStatic()) {
16002                        pw.print(" (low-ram)");
16003                    }
16004                    if (ActivityManager.isHighEndGfx()) {
16005                        pw.print(" (high-end-gfx)");
16006                    }
16007                    pw.println();
16008                } else {
16009                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16010                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16011                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16012                    pw.print("tuning,");
16013                    pw.print(ActivityManager.staticGetMemoryClass());
16014                    pw.print(',');
16015                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16016                    pw.print(',');
16017                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16018                    if (ActivityManager.isLowRamDeviceStatic()) {
16019                        pw.print(",low-ram");
16020                    }
16021                    if (ActivityManager.isHighEndGfx()) {
16022                        pw.print(",high-end-gfx");
16023                    }
16024                    pw.println();
16025                }
16026            }
16027        }
16028    }
16029
16030    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16031            long memtrack, String name) {
16032        sb.append("  ");
16033        sb.append(ProcessList.makeOomAdjString(oomAdj));
16034        sb.append(' ');
16035        sb.append(ProcessList.makeProcStateString(procState));
16036        sb.append(' ');
16037        ProcessList.appendRamKb(sb, pss);
16038        sb.append(": ");
16039        sb.append(name);
16040        if (memtrack > 0) {
16041            sb.append(" (");
16042            sb.append(stringifyKBSize(memtrack));
16043            sb.append(" memtrack)");
16044        }
16045    }
16046
16047    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16048        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16049        sb.append(" (pid ");
16050        sb.append(mi.pid);
16051        sb.append(") ");
16052        sb.append(mi.adjType);
16053        sb.append('\n');
16054        if (mi.adjReason != null) {
16055            sb.append("                      ");
16056            sb.append(mi.adjReason);
16057            sb.append('\n');
16058        }
16059    }
16060
16061    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16062        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16063        for (int i=0, N=memInfos.size(); i<N; i++) {
16064            ProcessMemInfo mi = memInfos.get(i);
16065            infoMap.put(mi.pid, mi);
16066        }
16067        updateCpuStatsNow();
16068        long[] memtrackTmp = new long[1];
16069        synchronized (mProcessCpuTracker) {
16070            final int N = mProcessCpuTracker.countStats();
16071            for (int i=0; i<N; i++) {
16072                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16073                if (st.vsize > 0) {
16074                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16075                    if (pss > 0) {
16076                        if (infoMap.indexOfKey(st.pid) < 0) {
16077                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16078                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16079                            mi.pss = pss;
16080                            mi.memtrack = memtrackTmp[0];
16081                            memInfos.add(mi);
16082                        }
16083                    }
16084                }
16085            }
16086        }
16087
16088        long totalPss = 0;
16089        long totalMemtrack = 0;
16090        for (int i=0, N=memInfos.size(); i<N; i++) {
16091            ProcessMemInfo mi = memInfos.get(i);
16092            if (mi.pss == 0) {
16093                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16094                mi.memtrack = memtrackTmp[0];
16095            }
16096            totalPss += mi.pss;
16097            totalMemtrack += mi.memtrack;
16098        }
16099        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16100            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16101                if (lhs.oomAdj != rhs.oomAdj) {
16102                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16103                }
16104                if (lhs.pss != rhs.pss) {
16105                    return lhs.pss < rhs.pss ? 1 : -1;
16106                }
16107                return 0;
16108            }
16109        });
16110
16111        StringBuilder tag = new StringBuilder(128);
16112        StringBuilder stack = new StringBuilder(128);
16113        tag.append("Low on memory -- ");
16114        appendMemBucket(tag, totalPss, "total", false);
16115        appendMemBucket(stack, totalPss, "total", true);
16116
16117        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16118        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16119        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16120
16121        boolean firstLine = true;
16122        int lastOomAdj = Integer.MIN_VALUE;
16123        long extraNativeRam = 0;
16124        long extraNativeMemtrack = 0;
16125        long cachedPss = 0;
16126        for (int i=0, N=memInfos.size(); i<N; i++) {
16127            ProcessMemInfo mi = memInfos.get(i);
16128
16129            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16130                cachedPss += mi.pss;
16131            }
16132
16133            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16134                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16135                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16136                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16137                if (lastOomAdj != mi.oomAdj) {
16138                    lastOomAdj = mi.oomAdj;
16139                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16140                        tag.append(" / ");
16141                    }
16142                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16143                        if (firstLine) {
16144                            stack.append(":");
16145                            firstLine = false;
16146                        }
16147                        stack.append("\n\t at ");
16148                    } else {
16149                        stack.append("$");
16150                    }
16151                } else {
16152                    tag.append(" ");
16153                    stack.append("$");
16154                }
16155                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16156                    appendMemBucket(tag, mi.pss, mi.name, false);
16157                }
16158                appendMemBucket(stack, mi.pss, mi.name, true);
16159                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16160                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16161                    stack.append("(");
16162                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16163                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16164                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16165                            stack.append(":");
16166                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16167                        }
16168                    }
16169                    stack.append(")");
16170                }
16171            }
16172
16173            appendMemInfo(fullNativeBuilder, mi);
16174            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16175                // The short form only has native processes that are >= 512K.
16176                if (mi.pss >= 512) {
16177                    appendMemInfo(shortNativeBuilder, mi);
16178                } else {
16179                    extraNativeRam += mi.pss;
16180                    extraNativeMemtrack += mi.memtrack;
16181                }
16182            } else {
16183                // Short form has all other details, but if we have collected RAM
16184                // from smaller native processes let's dump a summary of that.
16185                if (extraNativeRam > 0) {
16186                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16187                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16188                    shortNativeBuilder.append('\n');
16189                    extraNativeRam = 0;
16190                }
16191                appendMemInfo(fullJavaBuilder, mi);
16192            }
16193        }
16194
16195        fullJavaBuilder.append("           ");
16196        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16197        fullJavaBuilder.append(": TOTAL");
16198        if (totalMemtrack > 0) {
16199            fullJavaBuilder.append(" (");
16200            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16201            fullJavaBuilder.append(" memtrack)");
16202        } else {
16203        }
16204        fullJavaBuilder.append("\n");
16205
16206        MemInfoReader memInfo = new MemInfoReader();
16207        memInfo.readMemInfo();
16208        final long[] infos = memInfo.getRawInfo();
16209
16210        StringBuilder memInfoBuilder = new StringBuilder(1024);
16211        Debug.getMemInfo(infos);
16212        memInfoBuilder.append("  MemInfo: ");
16213        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16214        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16215        memInfoBuilder.append(stringifyKBSize(
16216                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16217        memInfoBuilder.append(stringifyKBSize(
16218                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16219        memInfoBuilder.append(stringifyKBSize(
16220                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16221        memInfoBuilder.append("           ");
16222        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16223        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16224        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16225        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16226        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16227            memInfoBuilder.append("  ZRAM: ");
16228            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16229            memInfoBuilder.append(" RAM, ");
16230            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16231            memInfoBuilder.append(" swap total, ");
16232            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16233            memInfoBuilder.append(" swap free\n");
16234        }
16235        final long[] ksm = getKsmInfo();
16236        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16237                || ksm[KSM_VOLATILE] != 0) {
16238            memInfoBuilder.append("  KSM: ");
16239            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16240            memInfoBuilder.append(" saved from shared ");
16241            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16242            memInfoBuilder.append("\n       ");
16243            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16244            memInfoBuilder.append(" unshared; ");
16245            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16246            memInfoBuilder.append(" volatile\n");
16247        }
16248        memInfoBuilder.append("  Free RAM: ");
16249        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16250                + memInfo.getFreeSizeKb()));
16251        memInfoBuilder.append("\n");
16252        memInfoBuilder.append("  Used RAM: ");
16253        memInfoBuilder.append(stringifyKBSize(
16254                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16255        memInfoBuilder.append("\n");
16256        memInfoBuilder.append("  Lost RAM: ");
16257        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16258                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16259                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16260        memInfoBuilder.append("\n");
16261        Slog.i(TAG, "Low on memory:");
16262        Slog.i(TAG, shortNativeBuilder.toString());
16263        Slog.i(TAG, fullJavaBuilder.toString());
16264        Slog.i(TAG, memInfoBuilder.toString());
16265
16266        StringBuilder dropBuilder = new StringBuilder(1024);
16267        /*
16268        StringWriter oomSw = new StringWriter();
16269        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16270        StringWriter catSw = new StringWriter();
16271        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16272        String[] emptyArgs = new String[] { };
16273        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16274        oomPw.flush();
16275        String oomString = oomSw.toString();
16276        */
16277        dropBuilder.append("Low on memory:");
16278        dropBuilder.append(stack);
16279        dropBuilder.append('\n');
16280        dropBuilder.append(fullNativeBuilder);
16281        dropBuilder.append(fullJavaBuilder);
16282        dropBuilder.append('\n');
16283        dropBuilder.append(memInfoBuilder);
16284        dropBuilder.append('\n');
16285        /*
16286        dropBuilder.append(oomString);
16287        dropBuilder.append('\n');
16288        */
16289        StringWriter catSw = new StringWriter();
16290        synchronized (ActivityManagerService.this) {
16291            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16292            String[] emptyArgs = new String[] { };
16293            catPw.println();
16294            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16295            catPw.println();
16296            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16297                    false, null).dumpLocked();
16298            catPw.println();
16299            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16300            catPw.flush();
16301        }
16302        dropBuilder.append(catSw.toString());
16303        addErrorToDropBox("lowmem", null, "system_server", null,
16304                null, tag.toString(), dropBuilder.toString(), null, null);
16305        //Slog.i(TAG, "Sent to dropbox:");
16306        //Slog.i(TAG, dropBuilder.toString());
16307        synchronized (ActivityManagerService.this) {
16308            long now = SystemClock.uptimeMillis();
16309            if (mLastMemUsageReportTime < now) {
16310                mLastMemUsageReportTime = now;
16311            }
16312        }
16313    }
16314
16315    /**
16316     * Searches array of arguments for the specified string
16317     * @param args array of argument strings
16318     * @param value value to search for
16319     * @return true if the value is contained in the array
16320     */
16321    private static boolean scanArgs(String[] args, String value) {
16322        if (args != null) {
16323            for (String arg : args) {
16324                if (value.equals(arg)) {
16325                    return true;
16326                }
16327            }
16328        }
16329        return false;
16330    }
16331
16332    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16333            ContentProviderRecord cpr, boolean always) {
16334        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16335
16336        if (!inLaunching || always) {
16337            synchronized (cpr) {
16338                cpr.launchingApp = null;
16339                cpr.notifyAll();
16340            }
16341            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16342            String names[] = cpr.info.authority.split(";");
16343            for (int j = 0; j < names.length; j++) {
16344                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16345            }
16346        }
16347
16348        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16349            ContentProviderConnection conn = cpr.connections.get(i);
16350            if (conn.waiting) {
16351                // If this connection is waiting for the provider, then we don't
16352                // need to mess with its process unless we are always removing
16353                // or for some reason the provider is not currently launching.
16354                if (inLaunching && !always) {
16355                    continue;
16356                }
16357            }
16358            ProcessRecord capp = conn.client;
16359            conn.dead = true;
16360            if (conn.stableCount > 0) {
16361                if (!capp.persistent && capp.thread != null
16362                        && capp.pid != 0
16363                        && capp.pid != MY_PID) {
16364                    capp.kill("depends on provider "
16365                            + cpr.name.flattenToShortString()
16366                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16367                }
16368            } else if (capp.thread != null && conn.provider.provider != null) {
16369                try {
16370                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16371                } catch (RemoteException e) {
16372                }
16373                // In the protocol here, we don't expect the client to correctly
16374                // clean up this connection, we'll just remove it.
16375                cpr.connections.remove(i);
16376                if (conn.client.conProviders.remove(conn)) {
16377                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16378                }
16379            }
16380        }
16381
16382        if (inLaunching && always) {
16383            mLaunchingProviders.remove(cpr);
16384        }
16385        return inLaunching;
16386    }
16387
16388    /**
16389     * Main code for cleaning up a process when it has gone away.  This is
16390     * called both as a result of the process dying, or directly when stopping
16391     * a process when running in single process mode.
16392     *
16393     * @return Returns true if the given process has been restarted, so the
16394     * app that was passed in must remain on the process lists.
16395     */
16396    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16397            boolean restarting, boolean allowRestart, int index) {
16398        if (index >= 0) {
16399            removeLruProcessLocked(app);
16400            ProcessList.remove(app.pid);
16401        }
16402
16403        mProcessesToGc.remove(app);
16404        mPendingPssProcesses.remove(app);
16405
16406        // Dismiss any open dialogs.
16407        if (app.crashDialog != null && !app.forceCrashReport) {
16408            app.crashDialog.dismiss();
16409            app.crashDialog = null;
16410        }
16411        if (app.anrDialog != null) {
16412            app.anrDialog.dismiss();
16413            app.anrDialog = null;
16414        }
16415        if (app.waitDialog != null) {
16416            app.waitDialog.dismiss();
16417            app.waitDialog = null;
16418        }
16419
16420        app.crashing = false;
16421        app.notResponding = false;
16422
16423        app.resetPackageList(mProcessStats);
16424        app.unlinkDeathRecipient();
16425        app.makeInactive(mProcessStats);
16426        app.waitingToKill = null;
16427        app.forcingToForeground = null;
16428        updateProcessForegroundLocked(app, false, false);
16429        app.foregroundActivities = false;
16430        app.hasShownUi = false;
16431        app.treatLikeActivity = false;
16432        app.hasAboveClient = false;
16433        app.hasClientActivities = false;
16434
16435        mServices.killServicesLocked(app, allowRestart);
16436
16437        boolean restart = false;
16438
16439        // Remove published content providers.
16440        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16441            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16442            final boolean always = app.bad || !allowRestart;
16443            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16444            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16445                // We left the provider in the launching list, need to
16446                // restart it.
16447                restart = true;
16448            }
16449
16450            cpr.provider = null;
16451            cpr.proc = null;
16452        }
16453        app.pubProviders.clear();
16454
16455        // Take care of any launching providers waiting for this process.
16456        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16457            restart = true;
16458        }
16459
16460        // Unregister from connected content providers.
16461        if (!app.conProviders.isEmpty()) {
16462            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16463                ContentProviderConnection conn = app.conProviders.get(i);
16464                conn.provider.connections.remove(conn);
16465                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16466                        conn.provider.name);
16467            }
16468            app.conProviders.clear();
16469        }
16470
16471        // At this point there may be remaining entries in mLaunchingProviders
16472        // where we were the only one waiting, so they are no longer of use.
16473        // Look for these and clean up if found.
16474        // XXX Commented out for now.  Trying to figure out a way to reproduce
16475        // the actual situation to identify what is actually going on.
16476        if (false) {
16477            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16478                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16479                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16480                    synchronized (cpr) {
16481                        cpr.launchingApp = null;
16482                        cpr.notifyAll();
16483                    }
16484                }
16485            }
16486        }
16487
16488        skipCurrentReceiverLocked(app);
16489
16490        // Unregister any receivers.
16491        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16492            removeReceiverLocked(app.receivers.valueAt(i));
16493        }
16494        app.receivers.clear();
16495
16496        // If the app is undergoing backup, tell the backup manager about it
16497        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16498            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16499                    + mBackupTarget.appInfo + " died during backup");
16500            try {
16501                IBackupManager bm = IBackupManager.Stub.asInterface(
16502                        ServiceManager.getService(Context.BACKUP_SERVICE));
16503                bm.agentDisconnected(app.info.packageName);
16504            } catch (RemoteException e) {
16505                // can't happen; backup manager is local
16506            }
16507        }
16508
16509        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16510            ProcessChangeItem item = mPendingProcessChanges.get(i);
16511            if (item.pid == app.pid) {
16512                mPendingProcessChanges.remove(i);
16513                mAvailProcessChanges.add(item);
16514            }
16515        }
16516        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16517                null).sendToTarget();
16518
16519        // If the caller is restarting this app, then leave it in its
16520        // current lists and let the caller take care of it.
16521        if (restarting) {
16522            return false;
16523        }
16524
16525        if (!app.persistent || app.isolated) {
16526            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16527                    "Removing non-persistent process during cleanup: " + app);
16528            removeProcessNameLocked(app.processName, app.uid);
16529            if (mHeavyWeightProcess == app) {
16530                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16531                        mHeavyWeightProcess.userId, 0));
16532                mHeavyWeightProcess = null;
16533            }
16534        } else if (!app.removed) {
16535            // This app is persistent, so we need to keep its record around.
16536            // If it is not already on the pending app list, add it there
16537            // and start a new process for it.
16538            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16539                mPersistentStartingProcesses.add(app);
16540                restart = true;
16541            }
16542        }
16543        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16544                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16545        mProcessesOnHold.remove(app);
16546
16547        if (app == mHomeProcess) {
16548            mHomeProcess = null;
16549        }
16550        if (app == mPreviousProcess) {
16551            mPreviousProcess = null;
16552        }
16553
16554        if (restart && !app.isolated) {
16555            // We have components that still need to be running in the
16556            // process, so re-launch it.
16557            if (index < 0) {
16558                ProcessList.remove(app.pid);
16559            }
16560            addProcessNameLocked(app);
16561            startProcessLocked(app, "restart", app.processName);
16562            return true;
16563        } else if (app.pid > 0 && app.pid != MY_PID) {
16564            // Goodbye!
16565            boolean removed;
16566            synchronized (mPidsSelfLocked) {
16567                mPidsSelfLocked.remove(app.pid);
16568                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16569            }
16570            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16571            if (app.isolated) {
16572                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16573            }
16574            app.setPid(0);
16575        }
16576        return false;
16577    }
16578
16579    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16580        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16581            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16582            if (cpr.launchingApp == app) {
16583                return true;
16584            }
16585        }
16586        return false;
16587    }
16588
16589    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16590        // Look through the content providers we are waiting to have launched,
16591        // and if any run in this process then either schedule a restart of
16592        // the process or kill the client waiting for it if this process has
16593        // gone bad.
16594        boolean restart = false;
16595        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16596            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16597            if (cpr.launchingApp == app) {
16598                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16599                    restart = true;
16600                } else {
16601                    removeDyingProviderLocked(app, cpr, true);
16602                }
16603            }
16604        }
16605        return restart;
16606    }
16607
16608    // =========================================================
16609    // SERVICES
16610    // =========================================================
16611
16612    @Override
16613    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16614            int flags) {
16615        enforceNotIsolatedCaller("getServices");
16616        synchronized (this) {
16617            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16618        }
16619    }
16620
16621    @Override
16622    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16623        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16624        synchronized (this) {
16625            return mServices.getRunningServiceControlPanelLocked(name);
16626        }
16627    }
16628
16629    @Override
16630    public ComponentName startService(IApplicationThread caller, Intent service,
16631            String resolvedType, String callingPackage, int userId)
16632            throws TransactionTooLargeException {
16633        enforceNotIsolatedCaller("startService");
16634        // Refuse possible leaked file descriptors
16635        if (service != null && service.hasFileDescriptors() == true) {
16636            throw new IllegalArgumentException("File descriptors passed in Intent");
16637        }
16638
16639        if (callingPackage == null) {
16640            throw new IllegalArgumentException("callingPackage cannot be null");
16641        }
16642
16643        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16644                "startService: " + service + " type=" + resolvedType);
16645        synchronized(this) {
16646            final int callingPid = Binder.getCallingPid();
16647            final int callingUid = Binder.getCallingUid();
16648            final long origId = Binder.clearCallingIdentity();
16649            ComponentName res = mServices.startServiceLocked(caller, service,
16650                    resolvedType, callingPid, callingUid, callingPackage, userId);
16651            Binder.restoreCallingIdentity(origId);
16652            return res;
16653        }
16654    }
16655
16656    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16657            String callingPackage, int userId)
16658            throws TransactionTooLargeException {
16659        synchronized(this) {
16660            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16661                    "startServiceInPackage: " + service + " type=" + resolvedType);
16662            final long origId = Binder.clearCallingIdentity();
16663            ComponentName res = mServices.startServiceLocked(null, service,
16664                    resolvedType, -1, uid, callingPackage, userId);
16665            Binder.restoreCallingIdentity(origId);
16666            return res;
16667        }
16668    }
16669
16670    @Override
16671    public int stopService(IApplicationThread caller, Intent service,
16672            String resolvedType, int userId) {
16673        enforceNotIsolatedCaller("stopService");
16674        // Refuse possible leaked file descriptors
16675        if (service != null && service.hasFileDescriptors() == true) {
16676            throw new IllegalArgumentException("File descriptors passed in Intent");
16677        }
16678
16679        synchronized(this) {
16680            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16681        }
16682    }
16683
16684    @Override
16685    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16686        enforceNotIsolatedCaller("peekService");
16687        // Refuse possible leaked file descriptors
16688        if (service != null && service.hasFileDescriptors() == true) {
16689            throw new IllegalArgumentException("File descriptors passed in Intent");
16690        }
16691
16692        if (callingPackage == null) {
16693            throw new IllegalArgumentException("callingPackage cannot be null");
16694        }
16695
16696        synchronized(this) {
16697            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16698        }
16699    }
16700
16701    @Override
16702    public boolean stopServiceToken(ComponentName className, IBinder token,
16703            int startId) {
16704        synchronized(this) {
16705            return mServices.stopServiceTokenLocked(className, token, startId);
16706        }
16707    }
16708
16709    @Override
16710    public void setServiceForeground(ComponentName className, IBinder token,
16711            int id, Notification notification, int flags) {
16712        synchronized(this) {
16713            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16714        }
16715    }
16716
16717    @Override
16718    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16719            boolean requireFull, String name, String callerPackage) {
16720        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16721                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16722    }
16723
16724    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16725            String className, int flags) {
16726        boolean result = false;
16727        // For apps that don't have pre-defined UIDs, check for permission
16728        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16729            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16730                if (ActivityManager.checkUidPermission(
16731                        INTERACT_ACROSS_USERS,
16732                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16733                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16734                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16735                            + " requests FLAG_SINGLE_USER, but app does not hold "
16736                            + INTERACT_ACROSS_USERS;
16737                    Slog.w(TAG, msg);
16738                    throw new SecurityException(msg);
16739                }
16740                // Permission passed
16741                result = true;
16742            }
16743        } else if ("system".equals(componentProcessName)) {
16744            result = true;
16745        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16746            // Phone app and persistent apps are allowed to export singleuser providers.
16747            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16748                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16749        }
16750        if (DEBUG_MU) Slog.v(TAG_MU,
16751                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16752                + Integer.toHexString(flags) + ") = " + result);
16753        return result;
16754    }
16755
16756    /**
16757     * Checks to see if the caller is in the same app as the singleton
16758     * component, or the component is in a special app. It allows special apps
16759     * to export singleton components but prevents exporting singleton
16760     * components for regular apps.
16761     */
16762    boolean isValidSingletonCall(int callingUid, int componentUid) {
16763        int componentAppId = UserHandle.getAppId(componentUid);
16764        return UserHandle.isSameApp(callingUid, componentUid)
16765                || componentAppId == Process.SYSTEM_UID
16766                || componentAppId == Process.PHONE_UID
16767                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16768                        == PackageManager.PERMISSION_GRANTED;
16769    }
16770
16771    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16772            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16773            int userId) throws TransactionTooLargeException {
16774        enforceNotIsolatedCaller("bindService");
16775
16776        // Refuse possible leaked file descriptors
16777        if (service != null && service.hasFileDescriptors() == true) {
16778            throw new IllegalArgumentException("File descriptors passed in Intent");
16779        }
16780
16781        if (callingPackage == null) {
16782            throw new IllegalArgumentException("callingPackage cannot be null");
16783        }
16784
16785        synchronized(this) {
16786            return mServices.bindServiceLocked(caller, token, service,
16787                    resolvedType, connection, flags, callingPackage, userId);
16788        }
16789    }
16790
16791    public boolean unbindService(IServiceConnection connection) {
16792        synchronized (this) {
16793            return mServices.unbindServiceLocked(connection);
16794        }
16795    }
16796
16797    public void publishService(IBinder token, Intent intent, IBinder service) {
16798        // Refuse possible leaked file descriptors
16799        if (intent != null && intent.hasFileDescriptors() == true) {
16800            throw new IllegalArgumentException("File descriptors passed in Intent");
16801        }
16802
16803        synchronized(this) {
16804            if (!(token instanceof ServiceRecord)) {
16805                throw new IllegalArgumentException("Invalid service token");
16806            }
16807            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16808        }
16809    }
16810
16811    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16812        // Refuse possible leaked file descriptors
16813        if (intent != null && intent.hasFileDescriptors() == true) {
16814            throw new IllegalArgumentException("File descriptors passed in Intent");
16815        }
16816
16817        synchronized(this) {
16818            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16819        }
16820    }
16821
16822    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16823        synchronized(this) {
16824            if (!(token instanceof ServiceRecord)) {
16825                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16826                throw new IllegalArgumentException("Invalid service token");
16827            }
16828            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16829        }
16830    }
16831
16832    // =========================================================
16833    // BACKUP AND RESTORE
16834    // =========================================================
16835
16836    // Cause the target app to be launched if necessary and its backup agent
16837    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16838    // activity manager to announce its creation.
16839    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16840        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16841                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16842        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16843
16844        synchronized(this) {
16845            // !!! TODO: currently no check here that we're already bound
16846            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16847            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16848            synchronized (stats) {
16849                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16850            }
16851
16852            // Backup agent is now in use, its package can't be stopped.
16853            try {
16854                AppGlobals.getPackageManager().setPackageStoppedState(
16855                        app.packageName, false, UserHandle.getUserId(app.uid));
16856            } catch (RemoteException e) {
16857            } catch (IllegalArgumentException e) {
16858                Slog.w(TAG, "Failed trying to unstop package "
16859                        + app.packageName + ": " + e);
16860            }
16861
16862            BackupRecord r = new BackupRecord(ss, app, backupMode);
16863            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16864                    ? new ComponentName(app.packageName, app.backupAgentName)
16865                    : new ComponentName("android", "FullBackupAgent");
16866            // startProcessLocked() returns existing proc's record if it's already running
16867            ProcessRecord proc = startProcessLocked(app.processName, app,
16868                    false, 0, "backup", hostingName, false, false, false);
16869            if (proc == null) {
16870                Slog.e(TAG, "Unable to start backup agent process " + r);
16871                return false;
16872            }
16873
16874            // If the app is a regular app (uid >= 10000) and not the system server or phone
16875            // process, etc, then mark it as being in full backup so that certain calls to the
16876            // process can be blocked. This is not reset to false anywhere because we kill the
16877            // process after the full backup is done and the ProcessRecord will vaporize anyway.
16878            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16879                proc.inFullBackup = true;
16880            }
16881            r.app = proc;
16882            mBackupTarget = r;
16883            mBackupAppName = app.packageName;
16884
16885            // Try not to kill the process during backup
16886            updateOomAdjLocked(proc);
16887
16888            // If the process is already attached, schedule the creation of the backup agent now.
16889            // If it is not yet live, this will be done when it attaches to the framework.
16890            if (proc.thread != null) {
16891                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16892                try {
16893                    proc.thread.scheduleCreateBackupAgent(app,
16894                            compatibilityInfoForPackageLocked(app), backupMode);
16895                } catch (RemoteException e) {
16896                    // Will time out on the backup manager side
16897                }
16898            } else {
16899                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16900            }
16901            // Invariants: at this point, the target app process exists and the application
16902            // is either already running or in the process of coming up.  mBackupTarget and
16903            // mBackupAppName describe the app, so that when it binds back to the AM we
16904            // know that it's scheduled for a backup-agent operation.
16905        }
16906
16907        return true;
16908    }
16909
16910    @Override
16911    public void clearPendingBackup() {
16912        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16913        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16914
16915        synchronized (this) {
16916            mBackupTarget = null;
16917            mBackupAppName = null;
16918        }
16919    }
16920
16921    // A backup agent has just come up
16922    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16923        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16924                + " = " + agent);
16925
16926        synchronized(this) {
16927            if (!agentPackageName.equals(mBackupAppName)) {
16928                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16929                return;
16930            }
16931        }
16932
16933        long oldIdent = Binder.clearCallingIdentity();
16934        try {
16935            IBackupManager bm = IBackupManager.Stub.asInterface(
16936                    ServiceManager.getService(Context.BACKUP_SERVICE));
16937            bm.agentConnected(agentPackageName, agent);
16938        } catch (RemoteException e) {
16939            // can't happen; the backup manager service is local
16940        } catch (Exception e) {
16941            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16942            e.printStackTrace();
16943        } finally {
16944            Binder.restoreCallingIdentity(oldIdent);
16945        }
16946    }
16947
16948    // done with this agent
16949    public void unbindBackupAgent(ApplicationInfo appInfo) {
16950        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16951        if (appInfo == null) {
16952            Slog.w(TAG, "unbind backup agent for null app");
16953            return;
16954        }
16955
16956        synchronized(this) {
16957            try {
16958                if (mBackupAppName == null) {
16959                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16960                    return;
16961                }
16962
16963                if (!mBackupAppName.equals(appInfo.packageName)) {
16964                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16965                    return;
16966                }
16967
16968                // Not backing this app up any more; reset its OOM adjustment
16969                final ProcessRecord proc = mBackupTarget.app;
16970                updateOomAdjLocked(proc);
16971
16972                // If the app crashed during backup, 'thread' will be null here
16973                if (proc.thread != null) {
16974                    try {
16975                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16976                                compatibilityInfoForPackageLocked(appInfo));
16977                    } catch (Exception e) {
16978                        Slog.e(TAG, "Exception when unbinding backup agent:");
16979                        e.printStackTrace();
16980                    }
16981                }
16982            } finally {
16983                mBackupTarget = null;
16984                mBackupAppName = null;
16985            }
16986        }
16987    }
16988    // =========================================================
16989    // BROADCASTS
16990    // =========================================================
16991
16992    boolean isPendingBroadcastProcessLocked(int pid) {
16993        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16994                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16995    }
16996
16997    void skipPendingBroadcastLocked(int pid) {
16998            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16999            for (BroadcastQueue queue : mBroadcastQueues) {
17000                queue.skipPendingBroadcastLocked(pid);
17001            }
17002    }
17003
17004    // The app just attached; send any pending broadcasts that it should receive
17005    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17006        boolean didSomething = false;
17007        for (BroadcastQueue queue : mBroadcastQueues) {
17008            didSomething |= queue.sendPendingBroadcastsLocked(app);
17009        }
17010        return didSomething;
17011    }
17012
17013    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17014            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17015        enforceNotIsolatedCaller("registerReceiver");
17016        ArrayList<Intent> stickyIntents = null;
17017        ProcessRecord callerApp = null;
17018        int callingUid;
17019        int callingPid;
17020        synchronized(this) {
17021            if (caller != null) {
17022                callerApp = getRecordForAppLocked(caller);
17023                if (callerApp == null) {
17024                    throw new SecurityException(
17025                            "Unable to find app for caller " + caller
17026                            + " (pid=" + Binder.getCallingPid()
17027                            + ") when registering receiver " + receiver);
17028                }
17029                if (callerApp.info.uid != Process.SYSTEM_UID &&
17030                        !callerApp.pkgList.containsKey(callerPackage) &&
17031                        !"android".equals(callerPackage)) {
17032                    throw new SecurityException("Given caller package " + callerPackage
17033                            + " is not running in process " + callerApp);
17034                }
17035                callingUid = callerApp.info.uid;
17036                callingPid = callerApp.pid;
17037            } else {
17038                callerPackage = null;
17039                callingUid = Binder.getCallingUid();
17040                callingPid = Binder.getCallingPid();
17041            }
17042
17043            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17044                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17045
17046            Iterator<String> actions = filter.actionsIterator();
17047            if (actions == null) {
17048                ArrayList<String> noAction = new ArrayList<String>(1);
17049                noAction.add(null);
17050                actions = noAction.iterator();
17051            }
17052
17053            // Collect stickies of users
17054            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17055            while (actions.hasNext()) {
17056                String action = actions.next();
17057                for (int id : userIds) {
17058                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17059                    if (stickies != null) {
17060                        ArrayList<Intent> intents = stickies.get(action);
17061                        if (intents != null) {
17062                            if (stickyIntents == null) {
17063                                stickyIntents = new ArrayList<Intent>();
17064                            }
17065                            stickyIntents.addAll(intents);
17066                        }
17067                    }
17068                }
17069            }
17070        }
17071
17072        ArrayList<Intent> allSticky = null;
17073        if (stickyIntents != null) {
17074            final ContentResolver resolver = mContext.getContentResolver();
17075            // Look for any matching sticky broadcasts...
17076            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17077                Intent intent = stickyIntents.get(i);
17078                // If intent has scheme "content", it will need to acccess
17079                // provider that needs to lock mProviderMap in ActivityThread
17080                // and also it may need to wait application response, so we
17081                // cannot lock ActivityManagerService here.
17082                if (filter.match(resolver, intent, true, TAG) >= 0) {
17083                    if (allSticky == null) {
17084                        allSticky = new ArrayList<Intent>();
17085                    }
17086                    allSticky.add(intent);
17087                }
17088            }
17089        }
17090
17091        // The first sticky in the list is returned directly back to the client.
17092        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17093        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17094        if (receiver == null) {
17095            return sticky;
17096        }
17097
17098        synchronized (this) {
17099            if (callerApp != null && (callerApp.thread == null
17100                    || callerApp.thread.asBinder() != caller.asBinder())) {
17101                // Original caller already died
17102                return null;
17103            }
17104            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17105            if (rl == null) {
17106                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17107                        userId, receiver);
17108                if (rl.app != null) {
17109                    rl.app.receivers.add(rl);
17110                } else {
17111                    try {
17112                        receiver.asBinder().linkToDeath(rl, 0);
17113                    } catch (RemoteException e) {
17114                        return sticky;
17115                    }
17116                    rl.linkedToDeath = true;
17117                }
17118                mRegisteredReceivers.put(receiver.asBinder(), rl);
17119            } else if (rl.uid != callingUid) {
17120                throw new IllegalArgumentException(
17121                        "Receiver requested to register for uid " + callingUid
17122                        + " was previously registered for uid " + rl.uid);
17123            } else if (rl.pid != callingPid) {
17124                throw new IllegalArgumentException(
17125                        "Receiver requested to register for pid " + callingPid
17126                        + " was previously registered for pid " + rl.pid);
17127            } else if (rl.userId != userId) {
17128                throw new IllegalArgumentException(
17129                        "Receiver requested to register for user " + userId
17130                        + " was previously registered for user " + rl.userId);
17131            }
17132            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17133                    permission, callingUid, userId);
17134            rl.add(bf);
17135            if (!bf.debugCheck()) {
17136                Slog.w(TAG, "==> For Dynamic broadcast");
17137            }
17138            mReceiverResolver.addFilter(bf);
17139
17140            // Enqueue broadcasts for all existing stickies that match
17141            // this filter.
17142            if (allSticky != null) {
17143                ArrayList receivers = new ArrayList();
17144                receivers.add(bf);
17145
17146                final int stickyCount = allSticky.size();
17147                for (int i = 0; i < stickyCount; i++) {
17148                    Intent intent = allSticky.get(i);
17149                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17150                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17151                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17152                            null, 0, null, null, false, true, true, -1);
17153                    queue.enqueueParallelBroadcastLocked(r);
17154                    queue.scheduleBroadcastsLocked();
17155                }
17156            }
17157
17158            return sticky;
17159        }
17160    }
17161
17162    public void unregisterReceiver(IIntentReceiver receiver) {
17163        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17164
17165        final long origId = Binder.clearCallingIdentity();
17166        try {
17167            boolean doTrim = false;
17168
17169            synchronized(this) {
17170                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17171                if (rl != null) {
17172                    final BroadcastRecord r = rl.curBroadcast;
17173                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17174                        final boolean doNext = r.queue.finishReceiverLocked(
17175                                r, r.resultCode, r.resultData, r.resultExtras,
17176                                r.resultAbort, false);
17177                        if (doNext) {
17178                            doTrim = true;
17179                            r.queue.processNextBroadcast(false);
17180                        }
17181                    }
17182
17183                    if (rl.app != null) {
17184                        rl.app.receivers.remove(rl);
17185                    }
17186                    removeReceiverLocked(rl);
17187                    if (rl.linkedToDeath) {
17188                        rl.linkedToDeath = false;
17189                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17190                    }
17191                }
17192            }
17193
17194            // If we actually concluded any broadcasts, we might now be able
17195            // to trim the recipients' apps from our working set
17196            if (doTrim) {
17197                trimApplications();
17198                return;
17199            }
17200
17201        } finally {
17202            Binder.restoreCallingIdentity(origId);
17203        }
17204    }
17205
17206    void removeReceiverLocked(ReceiverList rl) {
17207        mRegisteredReceivers.remove(rl.receiver.asBinder());
17208        for (int i = rl.size() - 1; i >= 0; i--) {
17209            mReceiverResolver.removeFilter(rl.get(i));
17210        }
17211    }
17212
17213    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17214        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17215            ProcessRecord r = mLruProcesses.get(i);
17216            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17217                try {
17218                    r.thread.dispatchPackageBroadcast(cmd, packages);
17219                } catch (RemoteException ex) {
17220                }
17221            }
17222        }
17223    }
17224
17225    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17226            int callingUid, int[] users) {
17227        // TODO: come back and remove this assumption to triage all broadcasts
17228        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17229
17230        List<ResolveInfo> receivers = null;
17231        try {
17232            HashSet<ComponentName> singleUserReceivers = null;
17233            boolean scannedFirstReceivers = false;
17234            for (int user : users) {
17235                // Skip users that have Shell restrictions, with exception of always permitted
17236                // Shell broadcasts
17237                if (callingUid == Process.SHELL_UID
17238                        && mUserController.hasUserRestriction(
17239                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17240                        && !isPermittedShellBroadcast(intent)) {
17241                    continue;
17242                }
17243                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17244                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17245                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17246                    // If this is not the system user, we need to check for
17247                    // any receivers that should be filtered out.
17248                    for (int i=0; i<newReceivers.size(); i++) {
17249                        ResolveInfo ri = newReceivers.get(i);
17250                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17251                            newReceivers.remove(i);
17252                            i--;
17253                        }
17254                    }
17255                }
17256                if (newReceivers != null && newReceivers.size() == 0) {
17257                    newReceivers = null;
17258                }
17259                if (receivers == null) {
17260                    receivers = newReceivers;
17261                } else if (newReceivers != null) {
17262                    // We need to concatenate the additional receivers
17263                    // found with what we have do far.  This would be easy,
17264                    // but we also need to de-dup any receivers that are
17265                    // singleUser.
17266                    if (!scannedFirstReceivers) {
17267                        // Collect any single user receivers we had already retrieved.
17268                        scannedFirstReceivers = true;
17269                        for (int i=0; i<receivers.size(); i++) {
17270                            ResolveInfo ri = receivers.get(i);
17271                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17272                                ComponentName cn = new ComponentName(
17273                                        ri.activityInfo.packageName, ri.activityInfo.name);
17274                                if (singleUserReceivers == null) {
17275                                    singleUserReceivers = new HashSet<ComponentName>();
17276                                }
17277                                singleUserReceivers.add(cn);
17278                            }
17279                        }
17280                    }
17281                    // Add the new results to the existing results, tracking
17282                    // and de-dupping single user receivers.
17283                    for (int i=0; i<newReceivers.size(); i++) {
17284                        ResolveInfo ri = newReceivers.get(i);
17285                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17286                            ComponentName cn = new ComponentName(
17287                                    ri.activityInfo.packageName, ri.activityInfo.name);
17288                            if (singleUserReceivers == null) {
17289                                singleUserReceivers = new HashSet<ComponentName>();
17290                            }
17291                            if (!singleUserReceivers.contains(cn)) {
17292                                singleUserReceivers.add(cn);
17293                                receivers.add(ri);
17294                            }
17295                        } else {
17296                            receivers.add(ri);
17297                        }
17298                    }
17299                }
17300            }
17301        } catch (RemoteException ex) {
17302            // pm is in same process, this will never happen.
17303        }
17304        return receivers;
17305    }
17306
17307    private boolean isPermittedShellBroadcast(Intent intent) {
17308        // remote bugreport should always be allowed to be taken
17309        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17310    }
17311
17312    final int broadcastIntentLocked(ProcessRecord callerApp,
17313            String callerPackage, Intent intent, String resolvedType,
17314            IIntentReceiver resultTo, int resultCode, String resultData,
17315            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17316            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17317        intent = new Intent(intent);
17318
17319        // By default broadcasts do not go to stopped apps.
17320        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17321
17322        // If we have not finished booting, don't allow this to launch new processes.
17323        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17324            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17325        }
17326
17327        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17328                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17329                + " ordered=" + ordered + " userid=" + userId);
17330        if ((resultTo != null) && !ordered) {
17331            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17332        }
17333
17334        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17335                ALLOW_NON_FULL, "broadcast", callerPackage);
17336
17337        // Make sure that the user who is receiving this broadcast is running.
17338        // If not, we will just skip it. Make an exception for shutdown broadcasts
17339        // and upgrade steps.
17340
17341        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17342            if ((callingUid != Process.SYSTEM_UID
17343                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17344                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17345                Slog.w(TAG, "Skipping broadcast of " + intent
17346                        + ": user " + userId + " is stopped");
17347                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17348            }
17349        }
17350
17351        BroadcastOptions brOptions = null;
17352        if (bOptions != null) {
17353            brOptions = new BroadcastOptions(bOptions);
17354            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17355                // See if the caller is allowed to do this.  Note we are checking against
17356                // the actual real caller (not whoever provided the operation as say a
17357                // PendingIntent), because that who is actually supplied the arguments.
17358                if (checkComponentPermission(
17359                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17360                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17361                        != PackageManager.PERMISSION_GRANTED) {
17362                    String msg = "Permission Denial: " + intent.getAction()
17363                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17364                            + ", uid=" + callingUid + ")"
17365                            + " requires "
17366                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17367                    Slog.w(TAG, msg);
17368                    throw new SecurityException(msg);
17369                }
17370            }
17371        }
17372
17373        // Verify that protected broadcasts are only being sent by system code,
17374        // and that system code is only sending protected broadcasts.
17375        final String action = intent.getAction();
17376        final boolean isProtectedBroadcast;
17377        try {
17378            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17379        } catch (RemoteException e) {
17380            Slog.w(TAG, "Remote exception", e);
17381            return ActivityManager.BROADCAST_SUCCESS;
17382        }
17383
17384        final boolean isCallerSystem;
17385        switch (UserHandle.getAppId(callingUid)) {
17386            case Process.ROOT_UID:
17387            case Process.SYSTEM_UID:
17388            case Process.PHONE_UID:
17389            case Process.BLUETOOTH_UID:
17390            case Process.NFC_UID:
17391                isCallerSystem = true;
17392                break;
17393            default:
17394                isCallerSystem = (callerApp != null) && callerApp.persistent;
17395                break;
17396        }
17397
17398        if (isCallerSystem) {
17399            if (isProtectedBroadcast
17400                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17401                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17402                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17403                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17404                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17405                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17406                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17407                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17408                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17409                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17410                // Broadcast is either protected, or it's a public action that
17411                // we've relaxed, so it's fine for system internals to send.
17412            } else {
17413                // The vast majority of broadcasts sent from system internals
17414                // should be protected to avoid security holes, so yell loudly
17415                // to ensure we examine these cases.
17416                if (callerApp != null) {
17417                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17418                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17419                            new Throwable());
17420                } else {
17421                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17422                            + " from system uid " + UserHandle.formatUid(callingUid)
17423                            + " pkg " + callerPackage,
17424                            new Throwable());
17425                }
17426            }
17427
17428        } else {
17429            if (isProtectedBroadcast) {
17430                String msg = "Permission Denial: not allowed to send broadcast "
17431                        + action + " from pid="
17432                        + callingPid + ", uid=" + callingUid;
17433                Slog.w(TAG, msg);
17434                throw new SecurityException(msg);
17435
17436            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17437                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17438                // Special case for compatibility: we don't want apps to send this,
17439                // but historically it has not been protected and apps may be using it
17440                // to poke their own app widget.  So, instead of making it protected,
17441                // just limit it to the caller.
17442                if (callerPackage == null) {
17443                    String msg = "Permission Denial: not allowed to send broadcast "
17444                            + action + " from unknown caller.";
17445                    Slog.w(TAG, msg);
17446                    throw new SecurityException(msg);
17447                } else if (intent.getComponent() != null) {
17448                    // They are good enough to send to an explicit component...  verify
17449                    // it is being sent to the calling app.
17450                    if (!intent.getComponent().getPackageName().equals(
17451                            callerPackage)) {
17452                        String msg = "Permission Denial: not allowed to send broadcast "
17453                                + action + " to "
17454                                + intent.getComponent().getPackageName() + " from "
17455                                + callerPackage;
17456                        Slog.w(TAG, msg);
17457                        throw new SecurityException(msg);
17458                    }
17459                } else {
17460                    // Limit broadcast to their own package.
17461                    intent.setPackage(callerPackage);
17462                }
17463            }
17464        }
17465
17466        if (action != null) {
17467            switch (action) {
17468                case Intent.ACTION_UID_REMOVED:
17469                case Intent.ACTION_PACKAGE_REMOVED:
17470                case Intent.ACTION_PACKAGE_CHANGED:
17471                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17472                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17473                case Intent.ACTION_PACKAGES_SUSPENDED:
17474                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17475                    // Handle special intents: if this broadcast is from the package
17476                    // manager about a package being removed, we need to remove all of
17477                    // its activities from the history stack.
17478                    if (checkComponentPermission(
17479                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17480                            callingPid, callingUid, -1, true)
17481                            != PackageManager.PERMISSION_GRANTED) {
17482                        String msg = "Permission Denial: " + intent.getAction()
17483                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17484                                + ", uid=" + callingUid + ")"
17485                                + " requires "
17486                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17487                        Slog.w(TAG, msg);
17488                        throw new SecurityException(msg);
17489                    }
17490                    switch (action) {
17491                        case Intent.ACTION_UID_REMOVED:
17492                            final Bundle intentExtras = intent.getExtras();
17493                            final int uid = intentExtras != null
17494                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17495                            if (uid >= 0) {
17496                                mBatteryStatsService.removeUid(uid);
17497                                mAppOpsService.uidRemoved(uid);
17498                            }
17499                            break;
17500                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17501                            // If resources are unavailable just force stop all those packages
17502                            // and flush the attribute cache as well.
17503                            String list[] =
17504                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17505                            if (list != null && list.length > 0) {
17506                                for (int i = 0; i < list.length; i++) {
17507                                    forceStopPackageLocked(list[i], -1, false, true, true,
17508                                            false, false, userId, "storage unmount");
17509                                }
17510                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17511                                sendPackageBroadcastLocked(
17512                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17513                                        userId);
17514                            }
17515                            break;
17516                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17517                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17518                            break;
17519                        case Intent.ACTION_PACKAGE_REMOVED:
17520                        case Intent.ACTION_PACKAGE_CHANGED:
17521                            Uri data = intent.getData();
17522                            String ssp;
17523                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17524                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17525                                final boolean replacing =
17526                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17527                                final boolean killProcess =
17528                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17529                                final boolean fullUninstall = removed && !replacing;
17530                                if (killProcess) {
17531                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17532                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17533                                            false, true, true, false, fullUninstall, userId,
17534                                            removed ? "pkg removed" : "pkg changed");
17535                                }
17536                                if (removed) {
17537                                    final int cmd = killProcess
17538                                            ? IApplicationThread.PACKAGE_REMOVED
17539                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17540                                    sendPackageBroadcastLocked(cmd,
17541                                            new String[] {ssp}, userId);
17542                                    if (fullUninstall) {
17543                                        mAppOpsService.packageRemoved(
17544                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17545
17546                                        // Remove all permissions granted from/to this package
17547                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17548
17549                                        removeTasksByPackageNameLocked(ssp, userId);
17550                                        mBatteryStatsService.notePackageUninstalled(ssp);
17551                                    }
17552                                } else {
17553                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17554                                            intent.getStringArrayExtra(
17555                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17556                                }
17557                            }
17558                            break;
17559                        case Intent.ACTION_PACKAGES_SUSPENDED:
17560                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17561                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17562                                    intent.getAction());
17563                            final String[] packageNames = intent.getStringArrayExtra(
17564                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17565                            final int userHandle = intent.getIntExtra(
17566                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17567
17568                            synchronized(ActivityManagerService.this) {
17569                                mRecentTasks.onPackagesSuspendedChanged(
17570                                        packageNames, suspended, userHandle);
17571                            }
17572                            break;
17573                    }
17574                    break;
17575                case Intent.ACTION_PACKAGE_REPLACED:
17576                {
17577                    final Uri data = intent.getData();
17578                    final String ssp;
17579                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17580                        final ApplicationInfo aInfo =
17581                                getPackageManagerInternalLocked().getApplicationInfo(
17582                                        ssp,
17583                                        userId);
17584                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17585                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17586                                new String[] {ssp}, userId);
17587                    }
17588                    break;
17589                }
17590                case Intent.ACTION_PACKAGE_ADDED:
17591                {
17592                    // Special case for adding a package: by default turn on compatibility mode.
17593                    Uri data = intent.getData();
17594                    String ssp;
17595                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17596                        final boolean replacing =
17597                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17598                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17599
17600                        try {
17601                            ApplicationInfo ai = AppGlobals.getPackageManager().
17602                                    getApplicationInfo(ssp, 0, 0);
17603                            mBatteryStatsService.notePackageInstalled(ssp,
17604                                    ai != null ? ai.versionCode : 0);
17605                        } catch (RemoteException e) {
17606                        }
17607                    }
17608                    break;
17609                }
17610                case Intent.ACTION_TIMEZONE_CHANGED:
17611                    // If this is the time zone changed action, queue up a message that will reset
17612                    // the timezone of all currently running processes. This message will get
17613                    // queued up before the broadcast happens.
17614                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17615                    break;
17616                case Intent.ACTION_TIME_CHANGED:
17617                    // If the user set the time, let all running processes know.
17618                    final int is24Hour =
17619                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17620                                    : 0;
17621                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17622                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17623                    synchronized (stats) {
17624                        stats.noteCurrentTimeChangedLocked();
17625                    }
17626                    break;
17627                case Intent.ACTION_CLEAR_DNS_CACHE:
17628                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17629                    break;
17630                case Proxy.PROXY_CHANGE_ACTION:
17631                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17632                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17633                    break;
17634                case android.hardware.Camera.ACTION_NEW_PICTURE:
17635                case android.hardware.Camera.ACTION_NEW_VIDEO:
17636                    // These broadcasts are no longer allowed by the system, since they can
17637                    // cause significant thrashing at a crictical point (using the camera).
17638                    // Apps should use JobScehduler to monitor for media provider changes.
17639                    Slog.w(TAG, action + " no longer allowed; dropping from "
17640                            + UserHandle.formatUid(callingUid));
17641                    // Lie; we don't want to crash the app.
17642                    return ActivityManager.BROADCAST_SUCCESS;
17643            }
17644        }
17645
17646        // Add to the sticky list if requested.
17647        if (sticky) {
17648            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17649                    callingPid, callingUid)
17650                    != PackageManager.PERMISSION_GRANTED) {
17651                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17652                        + callingPid + ", uid=" + callingUid
17653                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17654                Slog.w(TAG, msg);
17655                throw new SecurityException(msg);
17656            }
17657            if (requiredPermissions != null && requiredPermissions.length > 0) {
17658                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17659                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17660                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17661            }
17662            if (intent.getComponent() != null) {
17663                throw new SecurityException(
17664                        "Sticky broadcasts can't target a specific component");
17665            }
17666            // We use userId directly here, since the "all" target is maintained
17667            // as a separate set of sticky broadcasts.
17668            if (userId != UserHandle.USER_ALL) {
17669                // But first, if this is not a broadcast to all users, then
17670                // make sure it doesn't conflict with an existing broadcast to
17671                // all users.
17672                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17673                        UserHandle.USER_ALL);
17674                if (stickies != null) {
17675                    ArrayList<Intent> list = stickies.get(intent.getAction());
17676                    if (list != null) {
17677                        int N = list.size();
17678                        int i;
17679                        for (i=0; i<N; i++) {
17680                            if (intent.filterEquals(list.get(i))) {
17681                                throw new IllegalArgumentException(
17682                                        "Sticky broadcast " + intent + " for user "
17683                                        + userId + " conflicts with existing global broadcast");
17684                            }
17685                        }
17686                    }
17687                }
17688            }
17689            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17690            if (stickies == null) {
17691                stickies = new ArrayMap<>();
17692                mStickyBroadcasts.put(userId, stickies);
17693            }
17694            ArrayList<Intent> list = stickies.get(intent.getAction());
17695            if (list == null) {
17696                list = new ArrayList<>();
17697                stickies.put(intent.getAction(), list);
17698            }
17699            final int stickiesCount = list.size();
17700            int i;
17701            for (i = 0; i < stickiesCount; i++) {
17702                if (intent.filterEquals(list.get(i))) {
17703                    // This sticky already exists, replace it.
17704                    list.set(i, new Intent(intent));
17705                    break;
17706                }
17707            }
17708            if (i >= stickiesCount) {
17709                list.add(new Intent(intent));
17710            }
17711        }
17712
17713        int[] users;
17714        if (userId == UserHandle.USER_ALL) {
17715            // Caller wants broadcast to go to all started users.
17716            users = mUserController.getStartedUserArrayLocked();
17717        } else {
17718            // Caller wants broadcast to go to one specific user.
17719            users = new int[] {userId};
17720        }
17721
17722        // Figure out who all will receive this broadcast.
17723        List receivers = null;
17724        List<BroadcastFilter> registeredReceivers = null;
17725        // Need to resolve the intent to interested receivers...
17726        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17727                 == 0) {
17728            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17729        }
17730        if (intent.getComponent() == null) {
17731            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17732                // Query one target user at a time, excluding shell-restricted users
17733                for (int i = 0; i < users.length; i++) {
17734                    if (mUserController.hasUserRestriction(
17735                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17736                        continue;
17737                    }
17738                    List<BroadcastFilter> registeredReceiversForUser =
17739                            mReceiverResolver.queryIntent(intent,
17740                                    resolvedType, false, users[i]);
17741                    if (registeredReceivers == null) {
17742                        registeredReceivers = registeredReceiversForUser;
17743                    } else if (registeredReceiversForUser != null) {
17744                        registeredReceivers.addAll(registeredReceiversForUser);
17745                    }
17746                }
17747            } else {
17748                registeredReceivers = mReceiverResolver.queryIntent(intent,
17749                        resolvedType, false, userId);
17750            }
17751        }
17752
17753        final boolean replacePending =
17754                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17755
17756        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17757                + " replacePending=" + replacePending);
17758
17759        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17760        if (!ordered && NR > 0) {
17761            // If we are not serializing this broadcast, then send the
17762            // registered receivers separately so they don't wait for the
17763            // components to be launched.
17764            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17765            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17766                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17767                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17768                    resultExtras, ordered, sticky, false, userId);
17769            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17770            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17771            if (!replaced) {
17772                queue.enqueueParallelBroadcastLocked(r);
17773                queue.scheduleBroadcastsLocked();
17774            }
17775            registeredReceivers = null;
17776            NR = 0;
17777        }
17778
17779        // Merge into one list.
17780        int ir = 0;
17781        if (receivers != null) {
17782            // A special case for PACKAGE_ADDED: do not allow the package
17783            // being added to see this broadcast.  This prevents them from
17784            // using this as a back door to get run as soon as they are
17785            // installed.  Maybe in the future we want to have a special install
17786            // broadcast or such for apps, but we'd like to deliberately make
17787            // this decision.
17788            String skipPackages[] = null;
17789            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17790                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17791                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17792                Uri data = intent.getData();
17793                if (data != null) {
17794                    String pkgName = data.getSchemeSpecificPart();
17795                    if (pkgName != null) {
17796                        skipPackages = new String[] { pkgName };
17797                    }
17798                }
17799            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17800                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17801            }
17802            if (skipPackages != null && (skipPackages.length > 0)) {
17803                for (String skipPackage : skipPackages) {
17804                    if (skipPackage != null) {
17805                        int NT = receivers.size();
17806                        for (int it=0; it<NT; it++) {
17807                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17808                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17809                                receivers.remove(it);
17810                                it--;
17811                                NT--;
17812                            }
17813                        }
17814                    }
17815                }
17816            }
17817
17818            int NT = receivers != null ? receivers.size() : 0;
17819            int it = 0;
17820            ResolveInfo curt = null;
17821            BroadcastFilter curr = null;
17822            while (it < NT && ir < NR) {
17823                if (curt == null) {
17824                    curt = (ResolveInfo)receivers.get(it);
17825                }
17826                if (curr == null) {
17827                    curr = registeredReceivers.get(ir);
17828                }
17829                if (curr.getPriority() >= curt.priority) {
17830                    // Insert this broadcast record into the final list.
17831                    receivers.add(it, curr);
17832                    ir++;
17833                    curr = null;
17834                    it++;
17835                    NT++;
17836                } else {
17837                    // Skip to the next ResolveInfo in the final list.
17838                    it++;
17839                    curt = null;
17840                }
17841            }
17842        }
17843        while (ir < NR) {
17844            if (receivers == null) {
17845                receivers = new ArrayList();
17846            }
17847            receivers.add(registeredReceivers.get(ir));
17848            ir++;
17849        }
17850
17851        if ((receivers != null && receivers.size() > 0)
17852                || resultTo != null) {
17853            BroadcastQueue queue = broadcastQueueForIntent(intent);
17854            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17855                    callerPackage, callingPid, callingUid, resolvedType,
17856                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17857                    resultData, resultExtras, ordered, sticky, false, userId);
17858
17859            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17860                    + ": prev had " + queue.mOrderedBroadcasts.size());
17861            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17862                    "Enqueueing broadcast " + r.intent.getAction());
17863
17864            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17865            if (!replaced) {
17866                queue.enqueueOrderedBroadcastLocked(r);
17867                queue.scheduleBroadcastsLocked();
17868            }
17869        }
17870
17871        return ActivityManager.BROADCAST_SUCCESS;
17872    }
17873
17874    final Intent verifyBroadcastLocked(Intent intent) {
17875        // Refuse possible leaked file descriptors
17876        if (intent != null && intent.hasFileDescriptors() == true) {
17877            throw new IllegalArgumentException("File descriptors passed in Intent");
17878        }
17879
17880        int flags = intent.getFlags();
17881
17882        if (!mProcessesReady) {
17883            // if the caller really truly claims to know what they're doing, go
17884            // ahead and allow the broadcast without launching any receivers
17885            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17886                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17887            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17888                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17889                        + " before boot completion");
17890                throw new IllegalStateException("Cannot broadcast before boot completed");
17891            }
17892        }
17893
17894        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17895            throw new IllegalArgumentException(
17896                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17897        }
17898
17899        return intent;
17900    }
17901
17902    public final int broadcastIntent(IApplicationThread caller,
17903            Intent intent, String resolvedType, IIntentReceiver resultTo,
17904            int resultCode, String resultData, Bundle resultExtras,
17905            String[] requiredPermissions, int appOp, Bundle bOptions,
17906            boolean serialized, boolean sticky, int userId) {
17907        enforceNotIsolatedCaller("broadcastIntent");
17908        synchronized(this) {
17909            intent = verifyBroadcastLocked(intent);
17910
17911            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17912            final int callingPid = Binder.getCallingPid();
17913            final int callingUid = Binder.getCallingUid();
17914            final long origId = Binder.clearCallingIdentity();
17915            int res = broadcastIntentLocked(callerApp,
17916                    callerApp != null ? callerApp.info.packageName : null,
17917                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17918                    requiredPermissions, appOp, bOptions, serialized, sticky,
17919                    callingPid, callingUid, userId);
17920            Binder.restoreCallingIdentity(origId);
17921            return res;
17922        }
17923    }
17924
17925
17926    int broadcastIntentInPackage(String packageName, int uid,
17927            Intent intent, String resolvedType, IIntentReceiver resultTo,
17928            int resultCode, String resultData, Bundle resultExtras,
17929            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17930            int userId) {
17931        synchronized(this) {
17932            intent = verifyBroadcastLocked(intent);
17933
17934            final long origId = Binder.clearCallingIdentity();
17935            String[] requiredPermissions = requiredPermission == null ? null
17936                    : new String[] {requiredPermission};
17937            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17938                    resultTo, resultCode, resultData, resultExtras,
17939                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17940                    sticky, -1, uid, userId);
17941            Binder.restoreCallingIdentity(origId);
17942            return res;
17943        }
17944    }
17945
17946    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17947        // Refuse possible leaked file descriptors
17948        if (intent != null && intent.hasFileDescriptors() == true) {
17949            throw new IllegalArgumentException("File descriptors passed in Intent");
17950        }
17951
17952        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17953                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17954
17955        synchronized(this) {
17956            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17957                    != PackageManager.PERMISSION_GRANTED) {
17958                String msg = "Permission Denial: unbroadcastIntent() from pid="
17959                        + Binder.getCallingPid()
17960                        + ", uid=" + Binder.getCallingUid()
17961                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17962                Slog.w(TAG, msg);
17963                throw new SecurityException(msg);
17964            }
17965            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17966            if (stickies != null) {
17967                ArrayList<Intent> list = stickies.get(intent.getAction());
17968                if (list != null) {
17969                    int N = list.size();
17970                    int i;
17971                    for (i=0; i<N; i++) {
17972                        if (intent.filterEquals(list.get(i))) {
17973                            list.remove(i);
17974                            break;
17975                        }
17976                    }
17977                    if (list.size() <= 0) {
17978                        stickies.remove(intent.getAction());
17979                    }
17980                }
17981                if (stickies.size() <= 0) {
17982                    mStickyBroadcasts.remove(userId);
17983                }
17984            }
17985        }
17986    }
17987
17988    void backgroundServicesFinishedLocked(int userId) {
17989        for (BroadcastQueue queue : mBroadcastQueues) {
17990            queue.backgroundServicesFinishedLocked(userId);
17991        }
17992    }
17993
17994    public void finishReceiver(IBinder who, int resultCode, String resultData,
17995            Bundle resultExtras, boolean resultAbort, int flags) {
17996        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17997
17998        // Refuse possible leaked file descriptors
17999        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18000            throw new IllegalArgumentException("File descriptors passed in Bundle");
18001        }
18002
18003        final long origId = Binder.clearCallingIdentity();
18004        try {
18005            boolean doNext = false;
18006            BroadcastRecord r;
18007
18008            synchronized(this) {
18009                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18010                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18011                r = queue.getMatchingOrderedReceiver(who);
18012                if (r != null) {
18013                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18014                        resultData, resultExtras, resultAbort, true);
18015                }
18016            }
18017
18018            if (doNext) {
18019                r.queue.processNextBroadcast(false);
18020            }
18021            trimApplications();
18022        } finally {
18023            Binder.restoreCallingIdentity(origId);
18024        }
18025    }
18026
18027    // =========================================================
18028    // INSTRUMENTATION
18029    // =========================================================
18030
18031    public boolean startInstrumentation(ComponentName className,
18032            String profileFile, int flags, Bundle arguments,
18033            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18034            int userId, String abiOverride) {
18035        enforceNotIsolatedCaller("startInstrumentation");
18036        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18037                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18038        // Refuse possible leaked file descriptors
18039        if (arguments != null && arguments.hasFileDescriptors()) {
18040            throw new IllegalArgumentException("File descriptors passed in Bundle");
18041        }
18042
18043        synchronized(this) {
18044            InstrumentationInfo ii = null;
18045            ApplicationInfo ai = null;
18046            try {
18047                ii = mContext.getPackageManager().getInstrumentationInfo(
18048                    className, STOCK_PM_FLAGS);
18049                ai = AppGlobals.getPackageManager().getApplicationInfo(
18050                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18051            } catch (PackageManager.NameNotFoundException e) {
18052            } catch (RemoteException e) {
18053            }
18054            if (ii == null) {
18055                reportStartInstrumentationFailureLocked(watcher, className,
18056                        "Unable to find instrumentation info for: " + className);
18057                return false;
18058            }
18059            if (ai == null) {
18060                reportStartInstrumentationFailureLocked(watcher, className,
18061                        "Unable to find instrumentation target package: " + ii.targetPackage);
18062                return false;
18063            }
18064            if (!ai.hasCode()) {
18065                reportStartInstrumentationFailureLocked(watcher, className,
18066                        "Instrumentation target has no code: " + ii.targetPackage);
18067                return false;
18068            }
18069
18070            int match = mContext.getPackageManager().checkSignatures(
18071                    ii.targetPackage, ii.packageName);
18072            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18073                String msg = "Permission Denial: starting instrumentation "
18074                        + className + " from pid="
18075                        + Binder.getCallingPid()
18076                        + ", uid=" + Binder.getCallingPid()
18077                        + " not allowed because package " + ii.packageName
18078                        + " does not have a signature matching the target "
18079                        + ii.targetPackage;
18080                reportStartInstrumentationFailureLocked(watcher, className, msg);
18081                throw new SecurityException(msg);
18082            }
18083
18084            final long origId = Binder.clearCallingIdentity();
18085            // Instrumentation can kill and relaunch even persistent processes
18086            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18087                    "start instr");
18088            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18089            app.instrumentationClass = className;
18090            app.instrumentationInfo = ai;
18091            app.instrumentationProfileFile = profileFile;
18092            app.instrumentationArguments = arguments;
18093            app.instrumentationWatcher = watcher;
18094            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18095            app.instrumentationResultClass = className;
18096            Binder.restoreCallingIdentity(origId);
18097        }
18098
18099        return true;
18100    }
18101
18102    /**
18103     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18104     * error to the logs, but if somebody is watching, send the report there too.  This enables
18105     * the "am" command to report errors with more information.
18106     *
18107     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18108     * @param cn The component name of the instrumentation.
18109     * @param report The error report.
18110     */
18111    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18112            ComponentName cn, String report) {
18113        Slog.w(TAG, report);
18114        if (watcher != null) {
18115            Bundle results = new Bundle();
18116            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18117            results.putString("Error", report);
18118            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18119        }
18120    }
18121
18122    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18123        if (app.instrumentationWatcher != null) {
18124            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18125                    app.instrumentationClass, resultCode, results);
18126        }
18127
18128        // Can't call out of the system process with a lock held, so post a message.
18129        if (app.instrumentationUiAutomationConnection != null) {
18130            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18131                    app.instrumentationUiAutomationConnection).sendToTarget();
18132        }
18133
18134        app.instrumentationWatcher = null;
18135        app.instrumentationUiAutomationConnection = null;
18136        app.instrumentationClass = null;
18137        app.instrumentationInfo = null;
18138        app.instrumentationProfileFile = null;
18139        app.instrumentationArguments = null;
18140
18141        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18142                "finished inst");
18143    }
18144
18145    public void finishInstrumentation(IApplicationThread target,
18146            int resultCode, Bundle results) {
18147        int userId = UserHandle.getCallingUserId();
18148        // Refuse possible leaked file descriptors
18149        if (results != null && results.hasFileDescriptors()) {
18150            throw new IllegalArgumentException("File descriptors passed in Intent");
18151        }
18152
18153        synchronized(this) {
18154            ProcessRecord app = getRecordForAppLocked(target);
18155            if (app == null) {
18156                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18157                return;
18158            }
18159            final long origId = Binder.clearCallingIdentity();
18160            finishInstrumentationLocked(app, resultCode, results);
18161            Binder.restoreCallingIdentity(origId);
18162        }
18163    }
18164
18165    // =========================================================
18166    // CONFIGURATION
18167    // =========================================================
18168
18169    public ConfigurationInfo getDeviceConfigurationInfo() {
18170        ConfigurationInfo config = new ConfigurationInfo();
18171        synchronized (this) {
18172            config.reqTouchScreen = mConfiguration.touchscreen;
18173            config.reqKeyboardType = mConfiguration.keyboard;
18174            config.reqNavigation = mConfiguration.navigation;
18175            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18176                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18177                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18178            }
18179            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18180                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18181                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18182            }
18183            config.reqGlEsVersion = GL_ES_VERSION;
18184        }
18185        return config;
18186    }
18187
18188    ActivityStack getFocusedStack() {
18189        return mStackSupervisor.getFocusedStack();
18190    }
18191
18192    @Override
18193    public int getFocusedStackId() throws RemoteException {
18194        ActivityStack focusedStack = getFocusedStack();
18195        if (focusedStack != null) {
18196            return focusedStack.getStackId();
18197        }
18198        return -1;
18199    }
18200
18201    public Configuration getConfiguration() {
18202        Configuration ci;
18203        synchronized(this) {
18204            ci = new Configuration(mConfiguration);
18205            ci.userSetLocale = false;
18206        }
18207        return ci;
18208    }
18209
18210    @Override
18211    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18212        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18213        synchronized (this) {
18214            mSuppressResizeConfigChanges = suppress;
18215        }
18216    }
18217
18218    @Override
18219    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18220        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18221        if (fromStackId == HOME_STACK_ID) {
18222            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18223        }
18224        synchronized (this) {
18225            final long origId = Binder.clearCallingIdentity();
18226            try {
18227                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18228            } finally {
18229                Binder.restoreCallingIdentity(origId);
18230            }
18231        }
18232    }
18233
18234    @Override
18235    public void updatePersistentConfiguration(Configuration values) {
18236        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18237                "updateConfiguration()");
18238        enforceWriteSettingsPermission("updateConfiguration()");
18239        if (values == null) {
18240            throw new NullPointerException("Configuration must not be null");
18241        }
18242
18243        int userId = UserHandle.getCallingUserId();
18244
18245        synchronized(this) {
18246            final long origId = Binder.clearCallingIdentity();
18247            updateConfigurationLocked(values, null, false, true, userId);
18248            Binder.restoreCallingIdentity(origId);
18249        }
18250    }
18251
18252    private void updateFontScaleIfNeeded() {
18253        final int currentUserId;
18254        synchronized(this) {
18255            currentUserId = mUserController.getCurrentUserIdLocked();
18256        }
18257        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18258                FONT_SCALE, 1.0f, currentUserId);
18259        if (mConfiguration.fontScale != scaleFactor) {
18260            final Configuration configuration = mWindowManager.computeNewConfiguration();
18261            configuration.fontScale = scaleFactor;
18262            updatePersistentConfiguration(configuration);
18263        }
18264    }
18265
18266    private void enforceWriteSettingsPermission(String func) {
18267        int uid = Binder.getCallingUid();
18268        if (uid == Process.ROOT_UID) {
18269            return;
18270        }
18271
18272        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18273                Settings.getPackageNameForUid(mContext, uid), false)) {
18274            return;
18275        }
18276
18277        String msg = "Permission Denial: " + func + " from pid="
18278                + Binder.getCallingPid()
18279                + ", uid=" + uid
18280                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18281        Slog.w(TAG, msg);
18282        throw new SecurityException(msg);
18283    }
18284
18285    public void updateConfiguration(Configuration values) {
18286        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18287                "updateConfiguration()");
18288
18289        synchronized(this) {
18290            if (values == null && mWindowManager != null) {
18291                // sentinel: fetch the current configuration from the window manager
18292                values = mWindowManager.computeNewConfiguration();
18293            }
18294
18295            if (mWindowManager != null) {
18296                mProcessList.applyDisplaySize(mWindowManager);
18297            }
18298
18299            final long origId = Binder.clearCallingIdentity();
18300            if (values != null) {
18301                Settings.System.clearConfiguration(values);
18302            }
18303            updateConfigurationLocked(values, null, false);
18304            Binder.restoreCallingIdentity(origId);
18305        }
18306    }
18307
18308    void updateUserConfigurationLocked() {
18309        Configuration configuration = new Configuration(mConfiguration);
18310        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18311                mUserController.getCurrentUserIdLocked());
18312        updateConfigurationLocked(configuration, null, false);
18313    }
18314
18315    boolean updateConfigurationLocked(Configuration values,
18316            ActivityRecord starting, boolean initLocale) {
18317        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18318        return updateConfigurationLocked(values, starting, initLocale, false,
18319                UserHandle.USER_NULL);
18320    }
18321
18322    // To cache the list of supported system locales
18323    private String[] mSupportedSystemLocales = null;
18324
18325    /**
18326     * Do either or both things: (1) change the current configuration, and (2)
18327     * make sure the given activity is running with the (now) current
18328     * configuration.  Returns true if the activity has been left running, or
18329     * false if <var>starting</var> is being destroyed to match the new
18330     * configuration.
18331     *
18332     * @param userId is only used when persistent parameter is set to true to persist configuration
18333     *               for that particular user
18334     */
18335    private boolean updateConfigurationLocked(Configuration values,
18336            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18337        int changes = 0;
18338
18339        if (mWindowManager != null) {
18340            mWindowManager.deferSurfaceLayout();
18341        }
18342        if (values != null) {
18343            Configuration newConfig = new Configuration(mConfiguration);
18344            changes = newConfig.updateFrom(values);
18345            if (changes != 0) {
18346                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18347                        "Updating configuration to: " + values);
18348
18349                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18350
18351                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18352                    final LocaleList locales = values.getLocales();
18353                    int bestLocaleIndex = 0;
18354                    if (locales.size() > 1) {
18355                        if (mSupportedSystemLocales == null) {
18356                            mSupportedSystemLocales =
18357                                    Resources.getSystem().getAssets().getLocales();
18358                        }
18359                        bestLocaleIndex = Math.max(0,
18360                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18361                    }
18362                    SystemProperties.set("persist.sys.locale",
18363                            locales.get(bestLocaleIndex).toLanguageTag());
18364                    LocaleList.setDefault(locales, bestLocaleIndex);
18365                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18366                            locales.get(bestLocaleIndex)));
18367                }
18368
18369                mConfigurationSeq++;
18370                if (mConfigurationSeq <= 0) {
18371                    mConfigurationSeq = 1;
18372                }
18373                newConfig.seq = mConfigurationSeq;
18374                mConfiguration = newConfig;
18375                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18376                mUsageStatsService.reportConfigurationChange(newConfig,
18377                        mUserController.getCurrentUserIdLocked());
18378                //mUsageStatsService.noteStartConfig(newConfig);
18379
18380                final Configuration configCopy = new Configuration(mConfiguration);
18381
18382                // TODO: If our config changes, should we auto dismiss any currently
18383                // showing dialogs?
18384                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18385
18386                AttributeCache ac = AttributeCache.instance();
18387                if (ac != null) {
18388                    ac.updateConfiguration(configCopy);
18389                }
18390
18391                // Make sure all resources in our process are updated
18392                // right now, so that anyone who is going to retrieve
18393                // resource values after we return will be sure to get
18394                // the new ones.  This is especially important during
18395                // boot, where the first config change needs to guarantee
18396                // all resources have that config before following boot
18397                // code is executed.
18398                mSystemThread.applyConfigurationToResources(configCopy);
18399
18400                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18401                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18402                    msg.obj = new Configuration(configCopy);
18403                    msg.arg1 = userId;
18404                    mHandler.sendMessage(msg);
18405                }
18406
18407                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18408                if (isDensityChange) {
18409                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18410                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18411                }
18412
18413                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18414                    ProcessRecord app = mLruProcesses.get(i);
18415                    try {
18416                        if (app.thread != null) {
18417                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18418                                    + app.processName + " new config " + mConfiguration);
18419                            app.thread.scheduleConfigurationChanged(configCopy);
18420                        }
18421                    } catch (Exception e) {
18422                    }
18423                }
18424                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18425                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18426                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18427                        | Intent.FLAG_RECEIVER_FOREGROUND);
18428                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18429                        null, AppOpsManager.OP_NONE, null, false, false,
18430                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18431                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18432                    // Tell the shortcut manager that the system locale changed.  It needs to know
18433                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18434                    // we "push" from here, rather than having the service listen to the broadcast.
18435                    final ShortcutServiceInternal shortcutService =
18436                            LocalServices.getService(ShortcutServiceInternal.class);
18437                    if (shortcutService != null) {
18438                        shortcutService.onSystemLocaleChangedNoLock();
18439                    }
18440
18441                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18442                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18443                    if (!mProcessesReady) {
18444                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18445                    }
18446                    broadcastIntentLocked(null, null, intent,
18447                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18448                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18449                }
18450            }
18451            // Update the configuration with WM first and check if any of the stacks need to be
18452            // resized due to the configuration change. If so, resize the stacks now and do any
18453            // relaunches if necessary. This way we don't need to relaunch again below in
18454            // ensureActivityConfigurationLocked().
18455            if (mWindowManager != null) {
18456                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18457                if (resizedStacks != null) {
18458                    for (int stackId : resizedStacks) {
18459                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18460                        mStackSupervisor.resizeStackLocked(
18461                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18462                    }
18463                }
18464            }
18465        }
18466
18467        boolean kept = true;
18468        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18469        // mainStack is null during startup.
18470        if (mainStack != null) {
18471            if (changes != 0 && starting == null) {
18472                // If the configuration changed, and the caller is not already
18473                // in the process of starting an activity, then find the top
18474                // activity to check if its configuration needs to change.
18475                starting = mainStack.topRunningActivityLocked();
18476            }
18477
18478            if (starting != null) {
18479                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18480                // And we need to make sure at this point that all other activities
18481                // are made visible with the correct configuration.
18482                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18483                        !PRESERVE_WINDOWS);
18484            }
18485        }
18486        if (mWindowManager != null) {
18487            mWindowManager.continueSurfaceLayout();
18488        }
18489        return kept;
18490    }
18491
18492    /**
18493     * Decide based on the configuration whether we should shouw the ANR,
18494     * crash, etc dialogs.  The idea is that if there is no affordnace to
18495     * press the on-screen buttons, we shouldn't show the dialog.
18496     *
18497     * A thought: SystemUI might also want to get told about this, the Power
18498     * dialog / global actions also might want different behaviors.
18499     */
18500    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18501        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18502                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18503                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18504        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18505                                    == Configuration.UI_MODE_TYPE_CAR);
18506        return inputMethodExists && uiIsNotCarType && !inVrMode;
18507    }
18508
18509    @Override
18510    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18511        synchronized (this) {
18512            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18513            if (srec != null) {
18514                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18515            }
18516        }
18517        return false;
18518    }
18519
18520    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18521            Intent resultData) {
18522
18523        synchronized (this) {
18524            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18525            if (r != null) {
18526                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18527            }
18528            return false;
18529        }
18530    }
18531
18532    public int getLaunchedFromUid(IBinder activityToken) {
18533        ActivityRecord srec;
18534        synchronized (this) {
18535            srec = ActivityRecord.forTokenLocked(activityToken);
18536        }
18537        if (srec == null) {
18538            return -1;
18539        }
18540        return srec.launchedFromUid;
18541    }
18542
18543    public String getLaunchedFromPackage(IBinder activityToken) {
18544        ActivityRecord srec;
18545        synchronized (this) {
18546            srec = ActivityRecord.forTokenLocked(activityToken);
18547        }
18548        if (srec == null) {
18549            return null;
18550        }
18551        return srec.launchedFromPackage;
18552    }
18553
18554    // =========================================================
18555    // LIFETIME MANAGEMENT
18556    // =========================================================
18557
18558    // Returns which broadcast queue the app is the current [or imminent] receiver
18559    // on, or 'null' if the app is not an active broadcast recipient.
18560    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18561        BroadcastRecord r = app.curReceiver;
18562        if (r != null) {
18563            return r.queue;
18564        }
18565
18566        // It's not the current receiver, but it might be starting up to become one
18567        synchronized (this) {
18568            for (BroadcastQueue queue : mBroadcastQueues) {
18569                r = queue.mPendingBroadcast;
18570                if (r != null && r.curApp == app) {
18571                    // found it; report which queue it's in
18572                    return queue;
18573                }
18574            }
18575        }
18576
18577        return null;
18578    }
18579
18580    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18581            int targetUid, ComponentName targetComponent, String targetProcess) {
18582        if (!mTrackingAssociations) {
18583            return null;
18584        }
18585        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18586                = mAssociations.get(targetUid);
18587        if (components == null) {
18588            components = new ArrayMap<>();
18589            mAssociations.put(targetUid, components);
18590        }
18591        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18592        if (sourceUids == null) {
18593            sourceUids = new SparseArray<>();
18594            components.put(targetComponent, sourceUids);
18595        }
18596        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18597        if (sourceProcesses == null) {
18598            sourceProcesses = new ArrayMap<>();
18599            sourceUids.put(sourceUid, sourceProcesses);
18600        }
18601        Association ass = sourceProcesses.get(sourceProcess);
18602        if (ass == null) {
18603            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18604                    targetProcess);
18605            sourceProcesses.put(sourceProcess, ass);
18606        }
18607        ass.mCount++;
18608        ass.mNesting++;
18609        if (ass.mNesting == 1) {
18610            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18611            ass.mLastState = sourceState;
18612        }
18613        return ass;
18614    }
18615
18616    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18617            ComponentName targetComponent) {
18618        if (!mTrackingAssociations) {
18619            return;
18620        }
18621        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18622                = mAssociations.get(targetUid);
18623        if (components == null) {
18624            return;
18625        }
18626        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18627        if (sourceUids == null) {
18628            return;
18629        }
18630        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18631        if (sourceProcesses == null) {
18632            return;
18633        }
18634        Association ass = sourceProcesses.get(sourceProcess);
18635        if (ass == null || ass.mNesting <= 0) {
18636            return;
18637        }
18638        ass.mNesting--;
18639        if (ass.mNesting == 0) {
18640            long uptime = SystemClock.uptimeMillis();
18641            ass.mTime += uptime - ass.mStartTime;
18642            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18643                    += uptime - ass.mLastStateUptime;
18644            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18645        }
18646    }
18647
18648    private void noteUidProcessState(final int uid, final int state) {
18649        mBatteryStatsService.noteUidProcessState(uid, state);
18650        if (mTrackingAssociations) {
18651            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18652                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18653                        = mAssociations.valueAt(i1);
18654                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18655                    SparseArray<ArrayMap<String, Association>> sourceUids
18656                            = targetComponents.valueAt(i2);
18657                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18658                    if (sourceProcesses != null) {
18659                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18660                            Association ass = sourceProcesses.valueAt(i4);
18661                            if (ass.mNesting >= 1) {
18662                                // currently associated
18663                                long uptime = SystemClock.uptimeMillis();
18664                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18665                                        += uptime - ass.mLastStateUptime;
18666                                ass.mLastState = state;
18667                                ass.mLastStateUptime = uptime;
18668                            }
18669                        }
18670                    }
18671                }
18672            }
18673        }
18674    }
18675
18676    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18677            boolean doingAll, long now) {
18678        if (mAdjSeq == app.adjSeq) {
18679            // This adjustment has already been computed.
18680            return app.curRawAdj;
18681        }
18682
18683        if (app.thread == null) {
18684            app.adjSeq = mAdjSeq;
18685            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18686            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18687            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18688        }
18689
18690        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18691        app.adjSource = null;
18692        app.adjTarget = null;
18693        app.empty = false;
18694        app.cached = false;
18695
18696        final int activitiesSize = app.activities.size();
18697
18698        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18699            // The max adjustment doesn't allow this app to be anything
18700            // below foreground, so it is not worth doing work for it.
18701            app.adjType = "fixed";
18702            app.adjSeq = mAdjSeq;
18703            app.curRawAdj = app.maxAdj;
18704            app.foregroundActivities = false;
18705            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18706            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18707            // System processes can do UI, and when they do we want to have
18708            // them trim their memory after the user leaves the UI.  To
18709            // facilitate this, here we need to determine whether or not it
18710            // is currently showing UI.
18711            app.systemNoUi = true;
18712            if (app == TOP_APP) {
18713                app.systemNoUi = false;
18714                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18715                app.adjType = "pers-top-activity";
18716            } else if (activitiesSize > 0) {
18717                for (int j = 0; j < activitiesSize; j++) {
18718                    final ActivityRecord r = app.activities.get(j);
18719                    if (r.visible) {
18720                        app.systemNoUi = false;
18721                    }
18722                }
18723            }
18724            if (!app.systemNoUi) {
18725                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18726            }
18727            return (app.curAdj=app.maxAdj);
18728        }
18729
18730        app.systemNoUi = false;
18731
18732        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18733
18734        // Determine the importance of the process, starting with most
18735        // important to least, and assign an appropriate OOM adjustment.
18736        int adj;
18737        int schedGroup;
18738        int procState;
18739        boolean foregroundActivities = false;
18740        BroadcastQueue queue;
18741        if (app == TOP_APP) {
18742            // The last app on the list is the foreground app.
18743            adj = ProcessList.FOREGROUND_APP_ADJ;
18744            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18745            app.adjType = "top-activity";
18746            foregroundActivities = true;
18747            procState = PROCESS_STATE_CUR_TOP;
18748        } else if (app.instrumentationClass != null) {
18749            // Don't want to kill running instrumentation.
18750            adj = ProcessList.FOREGROUND_APP_ADJ;
18751            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18752            app.adjType = "instrumentation";
18753            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18754        } else if ((queue = isReceivingBroadcast(app)) != null) {
18755            // An app that is currently receiving a broadcast also
18756            // counts as being in the foreground for OOM killer purposes.
18757            // It's placed in a sched group based on the nature of the
18758            // broadcast as reflected by which queue it's active in.
18759            adj = ProcessList.FOREGROUND_APP_ADJ;
18760            schedGroup = (queue == mFgBroadcastQueue)
18761                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18762            app.adjType = "broadcast";
18763            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18764        } else if (app.executingServices.size() > 0) {
18765            // An app that is currently executing a service callback also
18766            // counts as being in the foreground.
18767            adj = ProcessList.FOREGROUND_APP_ADJ;
18768            schedGroup = app.execServicesFg ?
18769                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18770            app.adjType = "exec-service";
18771            procState = ActivityManager.PROCESS_STATE_SERVICE;
18772            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18773        } else {
18774            // As far as we know the process is empty.  We may change our mind later.
18775            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18776            // At this point we don't actually know the adjustment.  Use the cached adj
18777            // value that the caller wants us to.
18778            adj = cachedAdj;
18779            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18780            app.cached = true;
18781            app.empty = true;
18782            app.adjType = "cch-empty";
18783        }
18784
18785        // Examine all activities if not already foreground.
18786        if (!foregroundActivities && activitiesSize > 0) {
18787            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18788            for (int j = 0; j < activitiesSize; j++) {
18789                final ActivityRecord r = app.activities.get(j);
18790                if (r.app != app) {
18791                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18792                            + " instead of expected " + app);
18793                    if (r.app == null || (r.app.uid == app.uid)) {
18794                        // Only fix things up when they look sane
18795                        r.app = app;
18796                    } else {
18797                        continue;
18798                    }
18799                }
18800                if (r.visible) {
18801                    // App has a visible activity; only upgrade adjustment.
18802                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18803                        adj = ProcessList.VISIBLE_APP_ADJ;
18804                        app.adjType = "visible";
18805                    }
18806                    if (procState > PROCESS_STATE_CUR_TOP) {
18807                        procState = PROCESS_STATE_CUR_TOP;
18808                    }
18809                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18810                    app.cached = false;
18811                    app.empty = false;
18812                    foregroundActivities = true;
18813                    if (r.task != null && minLayer > 0) {
18814                        final int layer = r.task.mLayerRank;
18815                        if (layer >= 0 && minLayer > layer) {
18816                            minLayer = layer;
18817                        }
18818                    }
18819                    break;
18820                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18821                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18822                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18823                        app.adjType = "pausing";
18824                    }
18825                    if (procState > PROCESS_STATE_CUR_TOP) {
18826                        procState = PROCESS_STATE_CUR_TOP;
18827                    }
18828                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18829                    app.cached = false;
18830                    app.empty = false;
18831                    foregroundActivities = true;
18832                } else if (r.state == ActivityState.STOPPING) {
18833                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18834                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18835                        app.adjType = "stopping";
18836                    }
18837                    // For the process state, we will at this point consider the
18838                    // process to be cached.  It will be cached either as an activity
18839                    // or empty depending on whether the activity is finishing.  We do
18840                    // this so that we can treat the process as cached for purposes of
18841                    // memory trimming (determing current memory level, trim command to
18842                    // send to process) since there can be an arbitrary number of stopping
18843                    // processes and they should soon all go into the cached state.
18844                    if (!r.finishing) {
18845                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18846                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18847                        }
18848                    }
18849                    app.cached = false;
18850                    app.empty = false;
18851                    foregroundActivities = true;
18852                } else {
18853                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18854                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18855                        app.adjType = "cch-act";
18856                    }
18857                }
18858            }
18859            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18860                adj += minLayer;
18861            }
18862        }
18863
18864        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18865                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18866            if (app.foregroundServices) {
18867                // The user is aware of this app, so make it visible.
18868                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18869                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18870                app.cached = false;
18871                app.adjType = "fg-service";
18872                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18873            } else if (app.forcingToForeground != null) {
18874                // The user is aware of this app, so make it visible.
18875                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18876                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18877                app.cached = false;
18878                app.adjType = "force-fg";
18879                app.adjSource = app.forcingToForeground;
18880                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18881            }
18882        }
18883
18884        if (app == mHeavyWeightProcess) {
18885            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18886                // We don't want to kill the current heavy-weight process.
18887                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18888                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18889                app.cached = false;
18890                app.adjType = "heavy";
18891            }
18892            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18893                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18894            }
18895        }
18896
18897        if (app == mHomeProcess) {
18898            if (adj > ProcessList.HOME_APP_ADJ) {
18899                // This process is hosting what we currently consider to be the
18900                // home app, so we don't want to let it go into the background.
18901                adj = ProcessList.HOME_APP_ADJ;
18902                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18903                app.cached = false;
18904                app.adjType = "home";
18905            }
18906            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18907                procState = ActivityManager.PROCESS_STATE_HOME;
18908            }
18909        }
18910
18911        if (app == mPreviousProcess && app.activities.size() > 0) {
18912            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18913                // This was the previous process that showed UI to the user.
18914                // We want to try to keep it around more aggressively, to give
18915                // a good experience around switching between two apps.
18916                adj = ProcessList.PREVIOUS_APP_ADJ;
18917                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18918                app.cached = false;
18919                app.adjType = "previous";
18920            }
18921            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18922                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18923            }
18924        }
18925
18926        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18927                + " reason=" + app.adjType);
18928
18929        // By default, we use the computed adjustment.  It may be changed if
18930        // there are applications dependent on our services or providers, but
18931        // this gives us a baseline and makes sure we don't get into an
18932        // infinite recursion.
18933        app.adjSeq = mAdjSeq;
18934        app.curRawAdj = adj;
18935        app.hasStartedServices = false;
18936
18937        if (mBackupTarget != null && app == mBackupTarget.app) {
18938            // If possible we want to avoid killing apps while they're being backed up
18939            if (adj > ProcessList.BACKUP_APP_ADJ) {
18940                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18941                adj = ProcessList.BACKUP_APP_ADJ;
18942                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18943                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18944                }
18945                app.adjType = "backup";
18946                app.cached = false;
18947            }
18948            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18949                procState = ActivityManager.PROCESS_STATE_BACKUP;
18950            }
18951        }
18952
18953        boolean mayBeTop = false;
18954
18955        for (int is = app.services.size()-1;
18956                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18957                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18958                        || procState > ActivityManager.PROCESS_STATE_TOP);
18959                is--) {
18960            ServiceRecord s = app.services.valueAt(is);
18961            if (s.startRequested) {
18962                app.hasStartedServices = true;
18963                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18964                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18965                }
18966                if (app.hasShownUi && app != mHomeProcess) {
18967                    // If this process has shown some UI, let it immediately
18968                    // go to the LRU list because it may be pretty heavy with
18969                    // UI stuff.  We'll tag it with a label just to help
18970                    // debug and understand what is going on.
18971                    if (adj > ProcessList.SERVICE_ADJ) {
18972                        app.adjType = "cch-started-ui-services";
18973                    }
18974                } else {
18975                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18976                        // This service has seen some activity within
18977                        // recent memory, so we will keep its process ahead
18978                        // of the background processes.
18979                        if (adj > ProcessList.SERVICE_ADJ) {
18980                            adj = ProcessList.SERVICE_ADJ;
18981                            app.adjType = "started-services";
18982                            app.cached = false;
18983                        }
18984                    }
18985                    // If we have let the service slide into the background
18986                    // state, still have some text describing what it is doing
18987                    // even though the service no longer has an impact.
18988                    if (adj > ProcessList.SERVICE_ADJ) {
18989                        app.adjType = "cch-started-services";
18990                    }
18991                }
18992            }
18993            for (int conni = s.connections.size()-1;
18994                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18995                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18996                            || procState > ActivityManager.PROCESS_STATE_TOP);
18997                    conni--) {
18998                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18999                for (int i = 0;
19000                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19001                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19002                                || procState > ActivityManager.PROCESS_STATE_TOP);
19003                        i++) {
19004                    // XXX should compute this based on the max of
19005                    // all connected clients.
19006                    ConnectionRecord cr = clist.get(i);
19007                    if (cr.binding.client == app) {
19008                        // Binding to ourself is not interesting.
19009                        continue;
19010                    }
19011                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19012                        ProcessRecord client = cr.binding.client;
19013                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19014                                TOP_APP, doingAll, now);
19015                        int clientProcState = client.curProcState;
19016                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19017                            // If the other app is cached for any reason, for purposes here
19018                            // we are going to consider it empty.  The specific cached state
19019                            // doesn't propagate except under certain conditions.
19020                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19021                        }
19022                        String adjType = null;
19023                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19024                            // Not doing bind OOM management, so treat
19025                            // this guy more like a started service.
19026                            if (app.hasShownUi && app != mHomeProcess) {
19027                                // If this process has shown some UI, let it immediately
19028                                // go to the LRU list because it may be pretty heavy with
19029                                // UI stuff.  We'll tag it with a label just to help
19030                                // debug and understand what is going on.
19031                                if (adj > clientAdj) {
19032                                    adjType = "cch-bound-ui-services";
19033                                }
19034                                app.cached = false;
19035                                clientAdj = adj;
19036                                clientProcState = procState;
19037                            } else {
19038                                if (now >= (s.lastActivity
19039                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19040                                    // This service has not seen activity within
19041                                    // recent memory, so allow it to drop to the
19042                                    // LRU list if there is no other reason to keep
19043                                    // it around.  We'll also tag it with a label just
19044                                    // to help debug and undertand what is going on.
19045                                    if (adj > clientAdj) {
19046                                        adjType = "cch-bound-services";
19047                                    }
19048                                    clientAdj = adj;
19049                                }
19050                            }
19051                        }
19052                        if (adj > clientAdj) {
19053                            // If this process has recently shown UI, and
19054                            // the process that is binding to it is less
19055                            // important than being visible, then we don't
19056                            // care about the binding as much as we care
19057                            // about letting this process get into the LRU
19058                            // list to be killed and restarted if needed for
19059                            // memory.
19060                            if (app.hasShownUi && app != mHomeProcess
19061                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19062                                adjType = "cch-bound-ui-services";
19063                            } else {
19064                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19065                                        |Context.BIND_IMPORTANT)) != 0) {
19066                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19067                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19068                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19069                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19070                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19071                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19072                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19073                                    adj = clientAdj;
19074                                } else {
19075                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19076                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19077                                    }
19078                                }
19079                                if (!client.cached) {
19080                                    app.cached = false;
19081                                }
19082                                adjType = "service";
19083                            }
19084                        }
19085                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19086                            // This will treat important bound services identically to
19087                            // the top app, which may behave differently than generic
19088                            // foreground work.
19089                            if (client.curSchedGroup > schedGroup) {
19090                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19091                                    schedGroup = client.curSchedGroup;
19092                                } else {
19093                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19094                                }
19095                            }
19096                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19097                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19098                                    // Special handling of clients who are in the top state.
19099                                    // We *may* want to consider this process to be in the
19100                                    // top state as well, but only if there is not another
19101                                    // reason for it to be running.  Being on the top is a
19102                                    // special state, meaning you are specifically running
19103                                    // for the current top app.  If the process is already
19104                                    // running in the background for some other reason, it
19105                                    // is more important to continue considering it to be
19106                                    // in the background state.
19107                                    mayBeTop = true;
19108                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19109                                } else {
19110                                    // Special handling for above-top states (persistent
19111                                    // processes).  These should not bring the current process
19112                                    // into the top state, since they are not on top.  Instead
19113                                    // give them the best state after that.
19114                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19115                                        clientProcState =
19116                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19117                                    } else if (mWakefulness
19118                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19119                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19120                                                    != 0) {
19121                                        clientProcState =
19122                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19123                                    } else {
19124                                        clientProcState =
19125                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19126                                    }
19127                                }
19128                            }
19129                        } else {
19130                            if (clientProcState <
19131                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19132                                clientProcState =
19133                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19134                            }
19135                        }
19136                        if (procState > clientProcState) {
19137                            procState = clientProcState;
19138                        }
19139                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19140                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19141                            app.pendingUiClean = true;
19142                        }
19143                        if (adjType != null) {
19144                            app.adjType = adjType;
19145                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19146                                    .REASON_SERVICE_IN_USE;
19147                            app.adjSource = cr.binding.client;
19148                            app.adjSourceProcState = clientProcState;
19149                            app.adjTarget = s.name;
19150                        }
19151                    }
19152                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19153                        app.treatLikeActivity = true;
19154                    }
19155                    final ActivityRecord a = cr.activity;
19156                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19157                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19158                            (a.visible || a.state == ActivityState.RESUMED ||
19159                             a.state == ActivityState.PAUSING)) {
19160                            adj = ProcessList.FOREGROUND_APP_ADJ;
19161                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19162                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19163                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19164                                } else {
19165                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19166                                }
19167                            }
19168                            app.cached = false;
19169                            app.adjType = "service";
19170                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19171                                    .REASON_SERVICE_IN_USE;
19172                            app.adjSource = a;
19173                            app.adjSourceProcState = procState;
19174                            app.adjTarget = s.name;
19175                        }
19176                    }
19177                }
19178            }
19179        }
19180
19181        for (int provi = app.pubProviders.size()-1;
19182                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19183                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19184                        || procState > ActivityManager.PROCESS_STATE_TOP);
19185                provi--) {
19186            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19187            for (int i = cpr.connections.size()-1;
19188                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19189                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19190                            || procState > ActivityManager.PROCESS_STATE_TOP);
19191                    i--) {
19192                ContentProviderConnection conn = cpr.connections.get(i);
19193                ProcessRecord client = conn.client;
19194                if (client == app) {
19195                    // Being our own client is not interesting.
19196                    continue;
19197                }
19198                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19199                int clientProcState = client.curProcState;
19200                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19201                    // If the other app is cached for any reason, for purposes here
19202                    // we are going to consider it empty.
19203                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19204                }
19205                if (adj > clientAdj) {
19206                    if (app.hasShownUi && app != mHomeProcess
19207                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19208                        app.adjType = "cch-ui-provider";
19209                    } else {
19210                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19211                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19212                        app.adjType = "provider";
19213                    }
19214                    app.cached &= client.cached;
19215                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19216                            .REASON_PROVIDER_IN_USE;
19217                    app.adjSource = client;
19218                    app.adjSourceProcState = clientProcState;
19219                    app.adjTarget = cpr.name;
19220                }
19221                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19222                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19223                        // Special handling of clients who are in the top state.
19224                        // We *may* want to consider this process to be in the
19225                        // top state as well, but only if there is not another
19226                        // reason for it to be running.  Being on the top is a
19227                        // special state, meaning you are specifically running
19228                        // for the current top app.  If the process is already
19229                        // running in the background for some other reason, it
19230                        // is more important to continue considering it to be
19231                        // in the background state.
19232                        mayBeTop = true;
19233                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19234                    } else {
19235                        // Special handling for above-top states (persistent
19236                        // processes).  These should not bring the current process
19237                        // into the top state, since they are not on top.  Instead
19238                        // give them the best state after that.
19239                        clientProcState =
19240                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19241                    }
19242                }
19243                if (procState > clientProcState) {
19244                    procState = clientProcState;
19245                }
19246                if (client.curSchedGroup > schedGroup) {
19247                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19248                }
19249            }
19250            // If the provider has external (non-framework) process
19251            // dependencies, ensure that its adjustment is at least
19252            // FOREGROUND_APP_ADJ.
19253            if (cpr.hasExternalProcessHandles()) {
19254                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19255                    adj = ProcessList.FOREGROUND_APP_ADJ;
19256                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19257                    app.cached = false;
19258                    app.adjType = "provider";
19259                    app.adjTarget = cpr.name;
19260                }
19261                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19262                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19263                }
19264            }
19265        }
19266
19267        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19268            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19269                adj = ProcessList.PREVIOUS_APP_ADJ;
19270                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19271                app.cached = false;
19272                app.adjType = "provider";
19273            }
19274            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19275                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19276            }
19277        }
19278
19279        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19280            // A client of one of our services or providers is in the top state.  We
19281            // *may* want to be in the top state, but not if we are already running in
19282            // the background for some other reason.  For the decision here, we are going
19283            // to pick out a few specific states that we want to remain in when a client
19284            // is top (states that tend to be longer-term) and otherwise allow it to go
19285            // to the top state.
19286            switch (procState) {
19287                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19288                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19289                case ActivityManager.PROCESS_STATE_SERVICE:
19290                    // These all are longer-term states, so pull them up to the top
19291                    // of the background states, but not all the way to the top state.
19292                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19293                    break;
19294                default:
19295                    // Otherwise, top is a better choice, so take it.
19296                    procState = ActivityManager.PROCESS_STATE_TOP;
19297                    break;
19298            }
19299        }
19300
19301        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19302            if (app.hasClientActivities) {
19303                // This is a cached process, but with client activities.  Mark it so.
19304                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19305                app.adjType = "cch-client-act";
19306            } else if (app.treatLikeActivity) {
19307                // This is a cached process, but somebody wants us to treat it like it has
19308                // an activity, okay!
19309                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19310                app.adjType = "cch-as-act";
19311            }
19312        }
19313
19314        if (adj == ProcessList.SERVICE_ADJ) {
19315            if (doingAll) {
19316                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19317                mNewNumServiceProcs++;
19318                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19319                if (!app.serviceb) {
19320                    // This service isn't far enough down on the LRU list to
19321                    // normally be a B service, but if we are low on RAM and it
19322                    // is large we want to force it down since we would prefer to
19323                    // keep launcher over it.
19324                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19325                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19326                        app.serviceHighRam = true;
19327                        app.serviceb = true;
19328                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19329                    } else {
19330                        mNewNumAServiceProcs++;
19331                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19332                    }
19333                } else {
19334                    app.serviceHighRam = false;
19335                }
19336            }
19337            if (app.serviceb) {
19338                adj = ProcessList.SERVICE_B_ADJ;
19339            }
19340        }
19341
19342        app.curRawAdj = adj;
19343
19344        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19345        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19346        if (adj > app.maxAdj) {
19347            adj = app.maxAdj;
19348            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19349                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19350            }
19351        }
19352
19353        // Do final modification to adj.  Everything we do between here and applying
19354        // the final setAdj must be done in this function, because we will also use
19355        // it when computing the final cached adj later.  Note that we don't need to
19356        // worry about this for max adj above, since max adj will always be used to
19357        // keep it out of the cached vaues.
19358        app.curAdj = app.modifyRawOomAdj(adj);
19359        app.curSchedGroup = schedGroup;
19360        app.curProcState = procState;
19361        app.foregroundActivities = foregroundActivities;
19362
19363        return app.curRawAdj;
19364    }
19365
19366    /**
19367     * Record new PSS sample for a process.
19368     */
19369    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19370            long now) {
19371        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19372                swapPss * 1024);
19373        proc.lastPssTime = now;
19374        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19375        if (DEBUG_PSS) Slog.d(TAG_PSS,
19376                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19377                + " state=" + ProcessList.makeProcStateString(procState));
19378        if (proc.initialIdlePss == 0) {
19379            proc.initialIdlePss = pss;
19380        }
19381        proc.lastPss = pss;
19382        proc.lastSwapPss = swapPss;
19383        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19384            proc.lastCachedPss = pss;
19385            proc.lastCachedSwapPss = swapPss;
19386        }
19387
19388        final SparseArray<Pair<Long, String>> watchUids
19389                = mMemWatchProcesses.getMap().get(proc.processName);
19390        Long check = null;
19391        if (watchUids != null) {
19392            Pair<Long, String> val = watchUids.get(proc.uid);
19393            if (val == null) {
19394                val = watchUids.get(0);
19395            }
19396            if (val != null) {
19397                check = val.first;
19398            }
19399        }
19400        if (check != null) {
19401            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19402                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19403                if (!isDebuggable) {
19404                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19405                        isDebuggable = true;
19406                    }
19407                }
19408                if (isDebuggable) {
19409                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19410                    final ProcessRecord myProc = proc;
19411                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19412                    mMemWatchDumpProcName = proc.processName;
19413                    mMemWatchDumpFile = heapdumpFile.toString();
19414                    mMemWatchDumpPid = proc.pid;
19415                    mMemWatchDumpUid = proc.uid;
19416                    BackgroundThread.getHandler().post(new Runnable() {
19417                        @Override
19418                        public void run() {
19419                            revokeUriPermission(ActivityThread.currentActivityThread()
19420                                            .getApplicationThread(),
19421                                    DumpHeapActivity.JAVA_URI,
19422                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19423                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19424                                    UserHandle.myUserId());
19425                            ParcelFileDescriptor fd = null;
19426                            try {
19427                                heapdumpFile.delete();
19428                                fd = ParcelFileDescriptor.open(heapdumpFile,
19429                                        ParcelFileDescriptor.MODE_CREATE |
19430                                                ParcelFileDescriptor.MODE_TRUNCATE |
19431                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19432                                                ParcelFileDescriptor.MODE_APPEND);
19433                                IApplicationThread thread = myProc.thread;
19434                                if (thread != null) {
19435                                    try {
19436                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19437                                                "Requesting dump heap from "
19438                                                + myProc + " to " + heapdumpFile);
19439                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19440                                    } catch (RemoteException e) {
19441                                    }
19442                                }
19443                            } catch (FileNotFoundException e) {
19444                                e.printStackTrace();
19445                            } finally {
19446                                if (fd != null) {
19447                                    try {
19448                                        fd.close();
19449                                    } catch (IOException e) {
19450                                    }
19451                                }
19452                            }
19453                        }
19454                    });
19455                } else {
19456                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19457                            + ", but debugging not enabled");
19458                }
19459            }
19460        }
19461    }
19462
19463    /**
19464     * Schedule PSS collection of a process.
19465     */
19466    void requestPssLocked(ProcessRecord proc, int procState) {
19467        if (mPendingPssProcesses.contains(proc)) {
19468            return;
19469        }
19470        if (mPendingPssProcesses.size() == 0) {
19471            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19472        }
19473        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19474        proc.pssProcState = procState;
19475        mPendingPssProcesses.add(proc);
19476    }
19477
19478    /**
19479     * Schedule PSS collection of all processes.
19480     */
19481    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19482        if (!always) {
19483            if (now < (mLastFullPssTime +
19484                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19485                return;
19486            }
19487        }
19488        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19489        mLastFullPssTime = now;
19490        mFullPssPending = true;
19491        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19492        mPendingPssProcesses.clear();
19493        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19494            ProcessRecord app = mLruProcesses.get(i);
19495            if (app.thread == null
19496                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19497                continue;
19498            }
19499            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19500                app.pssProcState = app.setProcState;
19501                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19502                        mTestPssMode, isSleeping(), now);
19503                mPendingPssProcesses.add(app);
19504            }
19505        }
19506        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19507    }
19508
19509    public void setTestPssMode(boolean enabled) {
19510        synchronized (this) {
19511            mTestPssMode = enabled;
19512            if (enabled) {
19513                // Whenever we enable the mode, we want to take a snapshot all of current
19514                // process mem use.
19515                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19516            }
19517        }
19518    }
19519
19520    /**
19521     * Ask a given process to GC right now.
19522     */
19523    final void performAppGcLocked(ProcessRecord app) {
19524        try {
19525            app.lastRequestedGc = SystemClock.uptimeMillis();
19526            if (app.thread != null) {
19527                if (app.reportLowMemory) {
19528                    app.reportLowMemory = false;
19529                    app.thread.scheduleLowMemory();
19530                } else {
19531                    app.thread.processInBackground();
19532                }
19533            }
19534        } catch (Exception e) {
19535            // whatever.
19536        }
19537    }
19538
19539    /**
19540     * Returns true if things are idle enough to perform GCs.
19541     */
19542    private final boolean canGcNowLocked() {
19543        boolean processingBroadcasts = false;
19544        for (BroadcastQueue q : mBroadcastQueues) {
19545            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19546                processingBroadcasts = true;
19547            }
19548        }
19549        return !processingBroadcasts
19550                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19551    }
19552
19553    /**
19554     * Perform GCs on all processes that are waiting for it, but only
19555     * if things are idle.
19556     */
19557    final void performAppGcsLocked() {
19558        final int N = mProcessesToGc.size();
19559        if (N <= 0) {
19560            return;
19561        }
19562        if (canGcNowLocked()) {
19563            while (mProcessesToGc.size() > 0) {
19564                ProcessRecord proc = mProcessesToGc.remove(0);
19565                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19566                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19567                            <= SystemClock.uptimeMillis()) {
19568                        // To avoid spamming the system, we will GC processes one
19569                        // at a time, waiting a few seconds between each.
19570                        performAppGcLocked(proc);
19571                        scheduleAppGcsLocked();
19572                        return;
19573                    } else {
19574                        // It hasn't been long enough since we last GCed this
19575                        // process...  put it in the list to wait for its time.
19576                        addProcessToGcListLocked(proc);
19577                        break;
19578                    }
19579                }
19580            }
19581
19582            scheduleAppGcsLocked();
19583        }
19584    }
19585
19586    /**
19587     * If all looks good, perform GCs on all processes waiting for them.
19588     */
19589    final void performAppGcsIfAppropriateLocked() {
19590        if (canGcNowLocked()) {
19591            performAppGcsLocked();
19592            return;
19593        }
19594        // Still not idle, wait some more.
19595        scheduleAppGcsLocked();
19596    }
19597
19598    /**
19599     * Schedule the execution of all pending app GCs.
19600     */
19601    final void scheduleAppGcsLocked() {
19602        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19603
19604        if (mProcessesToGc.size() > 0) {
19605            // Schedule a GC for the time to the next process.
19606            ProcessRecord proc = mProcessesToGc.get(0);
19607            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19608
19609            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19610            long now = SystemClock.uptimeMillis();
19611            if (when < (now+GC_TIMEOUT)) {
19612                when = now + GC_TIMEOUT;
19613            }
19614            mHandler.sendMessageAtTime(msg, when);
19615        }
19616    }
19617
19618    /**
19619     * Add a process to the array of processes waiting to be GCed.  Keeps the
19620     * list in sorted order by the last GC time.  The process can't already be
19621     * on the list.
19622     */
19623    final void addProcessToGcListLocked(ProcessRecord proc) {
19624        boolean added = false;
19625        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19626            if (mProcessesToGc.get(i).lastRequestedGc <
19627                    proc.lastRequestedGc) {
19628                added = true;
19629                mProcessesToGc.add(i+1, proc);
19630                break;
19631            }
19632        }
19633        if (!added) {
19634            mProcessesToGc.add(0, proc);
19635        }
19636    }
19637
19638    /**
19639     * Set up to ask a process to GC itself.  This will either do it
19640     * immediately, or put it on the list of processes to gc the next
19641     * time things are idle.
19642     */
19643    final void scheduleAppGcLocked(ProcessRecord app) {
19644        long now = SystemClock.uptimeMillis();
19645        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19646            return;
19647        }
19648        if (!mProcessesToGc.contains(app)) {
19649            addProcessToGcListLocked(app);
19650            scheduleAppGcsLocked();
19651        }
19652    }
19653
19654    final void checkExcessivePowerUsageLocked(boolean doKills) {
19655        updateCpuStatsNow();
19656
19657        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19658        boolean doWakeKills = doKills;
19659        boolean doCpuKills = doKills;
19660        if (mLastPowerCheckRealtime == 0) {
19661            doWakeKills = false;
19662        }
19663        if (mLastPowerCheckUptime == 0) {
19664            doCpuKills = false;
19665        }
19666        if (stats.isScreenOn()) {
19667            doWakeKills = false;
19668        }
19669        final long curRealtime = SystemClock.elapsedRealtime();
19670        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19671        final long curUptime = SystemClock.uptimeMillis();
19672        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19673        mLastPowerCheckRealtime = curRealtime;
19674        mLastPowerCheckUptime = curUptime;
19675        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19676            doWakeKills = false;
19677        }
19678        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19679            doCpuKills = false;
19680        }
19681        int i = mLruProcesses.size();
19682        while (i > 0) {
19683            i--;
19684            ProcessRecord app = mLruProcesses.get(i);
19685            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19686                long wtime;
19687                synchronized (stats) {
19688                    wtime = stats.getProcessWakeTime(app.info.uid,
19689                            app.pid, curRealtime);
19690                }
19691                long wtimeUsed = wtime - app.lastWakeTime;
19692                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19693                if (DEBUG_POWER) {
19694                    StringBuilder sb = new StringBuilder(128);
19695                    sb.append("Wake for ");
19696                    app.toShortString(sb);
19697                    sb.append(": over ");
19698                    TimeUtils.formatDuration(realtimeSince, sb);
19699                    sb.append(" used ");
19700                    TimeUtils.formatDuration(wtimeUsed, sb);
19701                    sb.append(" (");
19702                    sb.append((wtimeUsed*100)/realtimeSince);
19703                    sb.append("%)");
19704                    Slog.i(TAG_POWER, sb.toString());
19705                    sb.setLength(0);
19706                    sb.append("CPU for ");
19707                    app.toShortString(sb);
19708                    sb.append(": over ");
19709                    TimeUtils.formatDuration(uptimeSince, sb);
19710                    sb.append(" used ");
19711                    TimeUtils.formatDuration(cputimeUsed, sb);
19712                    sb.append(" (");
19713                    sb.append((cputimeUsed*100)/uptimeSince);
19714                    sb.append("%)");
19715                    Slog.i(TAG_POWER, sb.toString());
19716                }
19717                // If a process has held a wake lock for more
19718                // than 50% of the time during this period,
19719                // that sounds bad.  Kill!
19720                if (doWakeKills && realtimeSince > 0
19721                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19722                    synchronized (stats) {
19723                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19724                                realtimeSince, wtimeUsed);
19725                    }
19726                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19727                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19728                } else if (doCpuKills && uptimeSince > 0
19729                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19730                    synchronized (stats) {
19731                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19732                                uptimeSince, cputimeUsed);
19733                    }
19734                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19735                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19736                } else {
19737                    app.lastWakeTime = wtime;
19738                    app.lastCpuTime = app.curCpuTime;
19739                }
19740            }
19741        }
19742    }
19743
19744    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19745            long nowElapsed) {
19746        boolean success = true;
19747
19748        if (app.curRawAdj != app.setRawAdj) {
19749            app.setRawAdj = app.curRawAdj;
19750        }
19751
19752        int changes = 0;
19753
19754        if (app.curAdj != app.setAdj) {
19755            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19756            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19757                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19758                    + app.adjType);
19759            app.setAdj = app.curAdj;
19760        }
19761
19762        if (app.setSchedGroup != app.curSchedGroup) {
19763            app.setSchedGroup = app.curSchedGroup;
19764            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19765                    "Setting sched group of " + app.processName
19766                    + " to " + app.curSchedGroup);
19767            if (app.waitingToKill != null && app.curReceiver == null
19768                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19769                app.kill(app.waitingToKill, true);
19770                success = false;
19771            } else {
19772                int processGroup;
19773                switch (app.curSchedGroup) {
19774                    case ProcessList.SCHED_GROUP_BACKGROUND:
19775                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19776                        break;
19777                    case ProcessList.SCHED_GROUP_TOP_APP:
19778                        processGroup = Process.THREAD_GROUP_TOP_APP;
19779                        break;
19780                    default:
19781                        processGroup = Process.THREAD_GROUP_DEFAULT;
19782                        break;
19783                }
19784                if (true) {
19785                    long oldId = Binder.clearCallingIdentity();
19786                    try {
19787                        Process.setProcessGroup(app.pid, processGroup);
19788                    } catch (Exception e) {
19789                        Slog.w(TAG, "Failed setting process group of " + app.pid
19790                                + " to " + app.curSchedGroup);
19791                        e.printStackTrace();
19792                    } finally {
19793                        Binder.restoreCallingIdentity(oldId);
19794                    }
19795                } else {
19796                    if (app.thread != null) {
19797                        try {
19798                            app.thread.setSchedulingGroup(processGroup);
19799                        } catch (RemoteException e) {
19800                        }
19801                    }
19802                }
19803            }
19804        }
19805        if (app.repForegroundActivities != app.foregroundActivities) {
19806            app.repForegroundActivities = app.foregroundActivities;
19807            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19808        }
19809        if (app.repProcState != app.curProcState) {
19810            app.repProcState = app.curProcState;
19811            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19812            if (app.thread != null) {
19813                try {
19814                    if (false) {
19815                        //RuntimeException h = new RuntimeException("here");
19816                        Slog.i(TAG, "Sending new process state " + app.repProcState
19817                                + " to " + app /*, h*/);
19818                    }
19819                    app.thread.setProcessState(app.repProcState);
19820                } catch (RemoteException e) {
19821                }
19822            }
19823        }
19824        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19825                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19826            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19827                // Experimental code to more aggressively collect pss while
19828                // running test...  the problem is that this tends to collect
19829                // the data right when a process is transitioning between process
19830                // states, which well tend to give noisy data.
19831                long start = SystemClock.uptimeMillis();
19832                long pss = Debug.getPss(app.pid, mTmpLong, null);
19833                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19834                mPendingPssProcesses.remove(app);
19835                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19836                        + " to " + app.curProcState + ": "
19837                        + (SystemClock.uptimeMillis()-start) + "ms");
19838            }
19839            app.lastStateTime = now;
19840            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19841                    mTestPssMode, isSleeping(), now);
19842            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19843                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19844                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19845                    + (app.nextPssTime-now) + ": " + app);
19846        } else {
19847            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19848                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19849                    mTestPssMode)))) {
19850                requestPssLocked(app, app.setProcState);
19851                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19852                        mTestPssMode, isSleeping(), now);
19853            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19854                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19855        }
19856        if (app.setProcState != app.curProcState) {
19857            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19858                    "Proc state change of " + app.processName
19859                            + " to " + app.curProcState);
19860            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19861            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19862            if (setImportant && !curImportant) {
19863                // This app is no longer something we consider important enough to allow to
19864                // use arbitrary amounts of battery power.  Note
19865                // its current wake lock time to later know to kill it if
19866                // it is not behaving well.
19867                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19868                synchronized (stats) {
19869                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19870                            app.pid, nowElapsed);
19871                }
19872                app.lastCpuTime = app.curCpuTime;
19873
19874            }
19875            // Inform UsageStats of important process state change
19876            // Must be called before updating setProcState
19877            maybeUpdateUsageStatsLocked(app, nowElapsed);
19878
19879            app.setProcState = app.curProcState;
19880            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19881                app.notCachedSinceIdle = false;
19882            }
19883            if (!doingAll) {
19884                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19885            } else {
19886                app.procStateChanged = true;
19887            }
19888        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19889                > USAGE_STATS_INTERACTION_INTERVAL) {
19890            // For apps that sit around for a long time in the interactive state, we need
19891            // to report this at least once a day so they don't go idle.
19892            maybeUpdateUsageStatsLocked(app, nowElapsed);
19893        }
19894
19895        if (changes != 0) {
19896            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19897                    "Changes in " + app + ": " + changes);
19898            int i = mPendingProcessChanges.size()-1;
19899            ProcessChangeItem item = null;
19900            while (i >= 0) {
19901                item = mPendingProcessChanges.get(i);
19902                if (item.pid == app.pid) {
19903                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19904                            "Re-using existing item: " + item);
19905                    break;
19906                }
19907                i--;
19908            }
19909            if (i < 0) {
19910                // No existing item in pending changes; need a new one.
19911                final int NA = mAvailProcessChanges.size();
19912                if (NA > 0) {
19913                    item = mAvailProcessChanges.remove(NA-1);
19914                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19915                            "Retrieving available item: " + item);
19916                } else {
19917                    item = new ProcessChangeItem();
19918                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19919                            "Allocating new item: " + item);
19920                }
19921                item.changes = 0;
19922                item.pid = app.pid;
19923                item.uid = app.info.uid;
19924                if (mPendingProcessChanges.size() == 0) {
19925                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19926                            "*** Enqueueing dispatch processes changed!");
19927                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19928                }
19929                mPendingProcessChanges.add(item);
19930            }
19931            item.changes |= changes;
19932            item.processState = app.repProcState;
19933            item.foregroundActivities = app.repForegroundActivities;
19934            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19935                    "Item " + Integer.toHexString(System.identityHashCode(item))
19936                    + " " + app.toShortString() + ": changes=" + item.changes
19937                    + " procState=" + item.processState
19938                    + " foreground=" + item.foregroundActivities
19939                    + " type=" + app.adjType + " source=" + app.adjSource
19940                    + " target=" + app.adjTarget);
19941        }
19942
19943        return success;
19944    }
19945
19946    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19947        final UidRecord.ChangeItem pendingChange;
19948        if (uidRec == null || uidRec.pendingChange == null) {
19949            if (mPendingUidChanges.size() == 0) {
19950                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19951                        "*** Enqueueing dispatch uid changed!");
19952                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19953            }
19954            final int NA = mAvailUidChanges.size();
19955            if (NA > 0) {
19956                pendingChange = mAvailUidChanges.remove(NA-1);
19957                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19958                        "Retrieving available item: " + pendingChange);
19959            } else {
19960                pendingChange = new UidRecord.ChangeItem();
19961                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19962                        "Allocating new item: " + pendingChange);
19963            }
19964            if (uidRec != null) {
19965                uidRec.pendingChange = pendingChange;
19966                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19967                    // If this uid is going away, and we haven't yet reported it is gone,
19968                    // then do so now.
19969                    change = UidRecord.CHANGE_GONE_IDLE;
19970                }
19971            } else if (uid < 0) {
19972                throw new IllegalArgumentException("No UidRecord or uid");
19973            }
19974            pendingChange.uidRecord = uidRec;
19975            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19976            mPendingUidChanges.add(pendingChange);
19977        } else {
19978            pendingChange = uidRec.pendingChange;
19979            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19980                change = UidRecord.CHANGE_GONE_IDLE;
19981            }
19982        }
19983        pendingChange.change = change;
19984        pendingChange.processState = uidRec != null
19985                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19986    }
19987
19988    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19989            String authority) {
19990        if (app == null) return;
19991        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19992            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19993            if (userState == null) return;
19994            final long now = SystemClock.elapsedRealtime();
19995            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19996            if (lastReported == null || lastReported < now - 60 * 1000L) {
19997                mUsageStatsService.reportContentProviderUsage(
19998                        authority, providerPkgName, app.userId);
19999                userState.mProviderLastReportedFg.put(authority, now);
20000            }
20001        }
20002    }
20003
20004    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20005        if (DEBUG_USAGE_STATS) {
20006            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20007                    + "] state changes: old = " + app.setProcState + ", new = "
20008                    + app.curProcState);
20009        }
20010        if (mUsageStatsService == null) {
20011            return;
20012        }
20013        boolean isInteraction;
20014        // To avoid some abuse patterns, we are going to be careful about what we consider
20015        // to be an app interaction.  Being the top activity doesn't count while the display
20016        // is sleeping, nor do short foreground services.
20017        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20018            isInteraction = true;
20019            app.fgInteractionTime = 0;
20020        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20021            if (app.fgInteractionTime == 0) {
20022                app.fgInteractionTime = nowElapsed;
20023                isInteraction = false;
20024            } else {
20025                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20026            }
20027        } else {
20028            isInteraction = app.curProcState
20029                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20030            app.fgInteractionTime = 0;
20031        }
20032        if (isInteraction && (!app.reportedInteraction
20033                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20034            app.interactionEventTime = nowElapsed;
20035            String[] packages = app.getPackageList();
20036            if (packages != null) {
20037                for (int i = 0; i < packages.length; i++) {
20038                    mUsageStatsService.reportEvent(packages[i], app.userId,
20039                            UsageEvents.Event.SYSTEM_INTERACTION);
20040                }
20041            }
20042        }
20043        app.reportedInteraction = isInteraction;
20044        if (!isInteraction) {
20045            app.interactionEventTime = 0;
20046        }
20047    }
20048
20049    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20050        if (proc.thread != null) {
20051            if (proc.baseProcessTracker != null) {
20052                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20053            }
20054        }
20055    }
20056
20057    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20058            ProcessRecord TOP_APP, boolean doingAll, long now) {
20059        if (app.thread == null) {
20060            return false;
20061        }
20062
20063        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20064
20065        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20066    }
20067
20068    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20069            boolean oomAdj) {
20070        if (isForeground != proc.foregroundServices) {
20071            proc.foregroundServices = isForeground;
20072            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20073                    proc.info.uid);
20074            if (isForeground) {
20075                if (curProcs == null) {
20076                    curProcs = new ArrayList<ProcessRecord>();
20077                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20078                }
20079                if (!curProcs.contains(proc)) {
20080                    curProcs.add(proc);
20081                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20082                            proc.info.packageName, proc.info.uid);
20083                }
20084            } else {
20085                if (curProcs != null) {
20086                    if (curProcs.remove(proc)) {
20087                        mBatteryStatsService.noteEvent(
20088                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20089                                proc.info.packageName, proc.info.uid);
20090                        if (curProcs.size() <= 0) {
20091                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20092                        }
20093                    }
20094                }
20095            }
20096            if (oomAdj) {
20097                updateOomAdjLocked();
20098            }
20099        }
20100    }
20101
20102    private final ActivityRecord resumedAppLocked() {
20103        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20104        String pkg;
20105        int uid;
20106        if (act != null) {
20107            pkg = act.packageName;
20108            uid = act.info.applicationInfo.uid;
20109        } else {
20110            pkg = null;
20111            uid = -1;
20112        }
20113        // Has the UID or resumed package name changed?
20114        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20115                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20116            if (mCurResumedPackage != null) {
20117                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20118                        mCurResumedPackage, mCurResumedUid);
20119            }
20120            mCurResumedPackage = pkg;
20121            mCurResumedUid = uid;
20122            if (mCurResumedPackage != null) {
20123                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20124                        mCurResumedPackage, mCurResumedUid);
20125            }
20126        }
20127        return act;
20128    }
20129
20130    final boolean updateOomAdjLocked(ProcessRecord app) {
20131        final ActivityRecord TOP_ACT = resumedAppLocked();
20132        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20133        final boolean wasCached = app.cached;
20134
20135        mAdjSeq++;
20136
20137        // This is the desired cached adjusment we want to tell it to use.
20138        // If our app is currently cached, we know it, and that is it.  Otherwise,
20139        // we don't know it yet, and it needs to now be cached we will then
20140        // need to do a complete oom adj.
20141        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20142                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20143        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20144                SystemClock.uptimeMillis());
20145        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20146            // Changed to/from cached state, so apps after it in the LRU
20147            // list may also be changed.
20148            updateOomAdjLocked();
20149        }
20150        return success;
20151    }
20152
20153    final void updateOomAdjLocked() {
20154        final ActivityRecord TOP_ACT = resumedAppLocked();
20155        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20156        final long now = SystemClock.uptimeMillis();
20157        final long nowElapsed = SystemClock.elapsedRealtime();
20158        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20159        final int N = mLruProcesses.size();
20160
20161        if (false) {
20162            RuntimeException e = new RuntimeException();
20163            e.fillInStackTrace();
20164            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20165        }
20166
20167        // Reset state in all uid records.
20168        for (int i=mActiveUids.size()-1; i>=0; i--) {
20169            final UidRecord uidRec = mActiveUids.valueAt(i);
20170            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20171                    "Starting update of " + uidRec);
20172            uidRec.reset();
20173        }
20174
20175        mStackSupervisor.rankTaskLayersIfNeeded();
20176
20177        mAdjSeq++;
20178        mNewNumServiceProcs = 0;
20179        mNewNumAServiceProcs = 0;
20180
20181        final int emptyProcessLimit;
20182        final int cachedProcessLimit;
20183        if (mProcessLimit <= 0) {
20184            emptyProcessLimit = cachedProcessLimit = 0;
20185        } else if (mProcessLimit == 1) {
20186            emptyProcessLimit = 1;
20187            cachedProcessLimit = 0;
20188        } else {
20189            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20190            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20191        }
20192
20193        // Let's determine how many processes we have running vs.
20194        // how many slots we have for background processes; we may want
20195        // to put multiple processes in a slot of there are enough of
20196        // them.
20197        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20198                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20199        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20200        if (numEmptyProcs > cachedProcessLimit) {
20201            // If there are more empty processes than our limit on cached
20202            // processes, then use the cached process limit for the factor.
20203            // This ensures that the really old empty processes get pushed
20204            // down to the bottom, so if we are running low on memory we will
20205            // have a better chance at keeping around more cached processes
20206            // instead of a gazillion empty processes.
20207            numEmptyProcs = cachedProcessLimit;
20208        }
20209        int emptyFactor = numEmptyProcs/numSlots;
20210        if (emptyFactor < 1) emptyFactor = 1;
20211        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20212        if (cachedFactor < 1) cachedFactor = 1;
20213        int stepCached = 0;
20214        int stepEmpty = 0;
20215        int numCached = 0;
20216        int numEmpty = 0;
20217        int numTrimming = 0;
20218
20219        mNumNonCachedProcs = 0;
20220        mNumCachedHiddenProcs = 0;
20221
20222        // First update the OOM adjustment for each of the
20223        // application processes based on their current state.
20224        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20225        int nextCachedAdj = curCachedAdj+1;
20226        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20227        int nextEmptyAdj = curEmptyAdj+2;
20228        for (int i=N-1; i>=0; i--) {
20229            ProcessRecord app = mLruProcesses.get(i);
20230            if (!app.killedByAm && app.thread != null) {
20231                app.procStateChanged = false;
20232                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20233
20234                // If we haven't yet assigned the final cached adj
20235                // to the process, do that now.
20236                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20237                    switch (app.curProcState) {
20238                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20239                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20240                            // This process is a cached process holding activities...
20241                            // assign it the next cached value for that type, and then
20242                            // step that cached level.
20243                            app.curRawAdj = curCachedAdj;
20244                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20245                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20246                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20247                                    + ")");
20248                            if (curCachedAdj != nextCachedAdj) {
20249                                stepCached++;
20250                                if (stepCached >= cachedFactor) {
20251                                    stepCached = 0;
20252                                    curCachedAdj = nextCachedAdj;
20253                                    nextCachedAdj += 2;
20254                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20255                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20256                                    }
20257                                }
20258                            }
20259                            break;
20260                        default:
20261                            // For everything else, assign next empty cached process
20262                            // level and bump that up.  Note that this means that
20263                            // long-running services that have dropped down to the
20264                            // cached level will be treated as empty (since their process
20265                            // state is still as a service), which is what we want.
20266                            app.curRawAdj = curEmptyAdj;
20267                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20268                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20269                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20270                                    + ")");
20271                            if (curEmptyAdj != nextEmptyAdj) {
20272                                stepEmpty++;
20273                                if (stepEmpty >= emptyFactor) {
20274                                    stepEmpty = 0;
20275                                    curEmptyAdj = nextEmptyAdj;
20276                                    nextEmptyAdj += 2;
20277                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20278                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20279                                    }
20280                                }
20281                            }
20282                            break;
20283                    }
20284                }
20285
20286                applyOomAdjLocked(app, true, now, nowElapsed);
20287
20288                // Count the number of process types.
20289                switch (app.curProcState) {
20290                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20291                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20292                        mNumCachedHiddenProcs++;
20293                        numCached++;
20294                        if (numCached > cachedProcessLimit) {
20295                            app.kill("cached #" + numCached, true);
20296                        }
20297                        break;
20298                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20299                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20300                                && app.lastActivityTime < oldTime) {
20301                            app.kill("empty for "
20302                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20303                                    / 1000) + "s", true);
20304                        } else {
20305                            numEmpty++;
20306                            if (numEmpty > emptyProcessLimit) {
20307                                app.kill("empty #" + numEmpty, true);
20308                            }
20309                        }
20310                        break;
20311                    default:
20312                        mNumNonCachedProcs++;
20313                        break;
20314                }
20315
20316                if (app.isolated && app.services.size() <= 0) {
20317                    // If this is an isolated process, and there are no
20318                    // services running in it, then the process is no longer
20319                    // needed.  We agressively kill these because we can by
20320                    // definition not re-use the same process again, and it is
20321                    // good to avoid having whatever code was running in them
20322                    // left sitting around after no longer needed.
20323                    app.kill("isolated not needed", true);
20324                } else {
20325                    // Keeping this process, update its uid.
20326                    final UidRecord uidRec = app.uidRecord;
20327                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20328                        uidRec.curProcState = app.curProcState;
20329                    }
20330                }
20331
20332                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20333                        && !app.killedByAm) {
20334                    numTrimming++;
20335                }
20336            }
20337        }
20338
20339        mNumServiceProcs = mNewNumServiceProcs;
20340
20341        // Now determine the memory trimming level of background processes.
20342        // Unfortunately we need to start at the back of the list to do this
20343        // properly.  We only do this if the number of background apps we
20344        // are managing to keep around is less than half the maximum we desire;
20345        // if we are keeping a good number around, we'll let them use whatever
20346        // memory they want.
20347        final int numCachedAndEmpty = numCached + numEmpty;
20348        int memFactor;
20349        if (numCached <= ProcessList.TRIM_CACHED_APPS
20350                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20351            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20352                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20353            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20354                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20355            } else {
20356                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20357            }
20358        } else {
20359            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20360        }
20361        // We always allow the memory level to go up (better).  We only allow it to go
20362        // down if we are in a state where that is allowed, *and* the total number of processes
20363        // has gone down since last time.
20364        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20365                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20366                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20367        if (memFactor > mLastMemoryLevel) {
20368            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20369                memFactor = mLastMemoryLevel;
20370                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20371            }
20372        }
20373        if (memFactor != mLastMemoryLevel) {
20374            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20375        }
20376        mLastMemoryLevel = memFactor;
20377        mLastNumProcesses = mLruProcesses.size();
20378        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20379        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20380        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20381            if (mLowRamStartTime == 0) {
20382                mLowRamStartTime = now;
20383            }
20384            int step = 0;
20385            int fgTrimLevel;
20386            switch (memFactor) {
20387                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20388                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20389                    break;
20390                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20391                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20392                    break;
20393                default:
20394                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20395                    break;
20396            }
20397            int factor = numTrimming/3;
20398            int minFactor = 2;
20399            if (mHomeProcess != null) minFactor++;
20400            if (mPreviousProcess != null) minFactor++;
20401            if (factor < minFactor) factor = minFactor;
20402            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20403            for (int i=N-1; i>=0; i--) {
20404                ProcessRecord app = mLruProcesses.get(i);
20405                if (allChanged || app.procStateChanged) {
20406                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20407                    app.procStateChanged = false;
20408                }
20409                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20410                        && !app.killedByAm) {
20411                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20412                        try {
20413                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20414                                    "Trimming memory of " + app.processName + " to " + curLevel);
20415                            app.thread.scheduleTrimMemory(curLevel);
20416                        } catch (RemoteException e) {
20417                        }
20418                        if (false) {
20419                            // For now we won't do this; our memory trimming seems
20420                            // to be good enough at this point that destroying
20421                            // activities causes more harm than good.
20422                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20423                                    && app != mHomeProcess && app != mPreviousProcess) {
20424                                // Need to do this on its own message because the stack may not
20425                                // be in a consistent state at this point.
20426                                // For these apps we will also finish their activities
20427                                // to help them free memory.
20428                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20429                            }
20430                        }
20431                    }
20432                    app.trimMemoryLevel = curLevel;
20433                    step++;
20434                    if (step >= factor) {
20435                        step = 0;
20436                        switch (curLevel) {
20437                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20438                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20439                                break;
20440                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20441                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20442                                break;
20443                        }
20444                    }
20445                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20446                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20447                            && app.thread != null) {
20448                        try {
20449                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20450                                    "Trimming memory of heavy-weight " + app.processName
20451                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20452                            app.thread.scheduleTrimMemory(
20453                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20454                        } catch (RemoteException e) {
20455                        }
20456                    }
20457                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20458                } else {
20459                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20460                            || app.systemNoUi) && app.pendingUiClean) {
20461                        // If this application is now in the background and it
20462                        // had done UI, then give it the special trim level to
20463                        // have it free UI resources.
20464                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20465                        if (app.trimMemoryLevel < level && app.thread != null) {
20466                            try {
20467                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20468                                        "Trimming memory of bg-ui " + app.processName
20469                                        + " to " + level);
20470                                app.thread.scheduleTrimMemory(level);
20471                            } catch (RemoteException e) {
20472                            }
20473                        }
20474                        app.pendingUiClean = false;
20475                    }
20476                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20477                        try {
20478                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20479                                    "Trimming memory of fg " + app.processName
20480                                    + " to " + fgTrimLevel);
20481                            app.thread.scheduleTrimMemory(fgTrimLevel);
20482                        } catch (RemoteException e) {
20483                        }
20484                    }
20485                    app.trimMemoryLevel = fgTrimLevel;
20486                }
20487            }
20488        } else {
20489            if (mLowRamStartTime != 0) {
20490                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20491                mLowRamStartTime = 0;
20492            }
20493            for (int i=N-1; i>=0; i--) {
20494                ProcessRecord app = mLruProcesses.get(i);
20495                if (allChanged || app.procStateChanged) {
20496                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20497                    app.procStateChanged = false;
20498                }
20499                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20500                        || app.systemNoUi) && app.pendingUiClean) {
20501                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20502                            && app.thread != null) {
20503                        try {
20504                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20505                                    "Trimming memory of ui hidden " + app.processName
20506                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20507                            app.thread.scheduleTrimMemory(
20508                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20509                        } catch (RemoteException e) {
20510                        }
20511                    }
20512                    app.pendingUiClean = false;
20513                }
20514                app.trimMemoryLevel = 0;
20515            }
20516        }
20517
20518        if (mAlwaysFinishActivities) {
20519            // Need to do this on its own message because the stack may not
20520            // be in a consistent state at this point.
20521            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20522        }
20523
20524        if (allChanged) {
20525            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20526        }
20527
20528        // Update from any uid changes.
20529        for (int i=mActiveUids.size()-1; i>=0; i--) {
20530            final UidRecord uidRec = mActiveUids.valueAt(i);
20531            int uidChange = UidRecord.CHANGE_PROCSTATE;
20532            if (uidRec.setProcState != uidRec.curProcState) {
20533                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20534                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20535                        + " to " + uidRec.curProcState);
20536                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20537                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20538                        uidRec.lastBackgroundTime = nowElapsed;
20539                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20540                            // Note: the background settle time is in elapsed realtime, while
20541                            // the handler time base is uptime.  All this means is that we may
20542                            // stop background uids later than we had intended, but that only
20543                            // happens because the device was sleeping so we are okay anyway.
20544                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20545                        }
20546                    }
20547                } else {
20548                    if (uidRec.idle) {
20549                        uidChange = UidRecord.CHANGE_ACTIVE;
20550                        uidRec.idle = false;
20551                    }
20552                    uidRec.lastBackgroundTime = 0;
20553                }
20554                uidRec.setProcState = uidRec.curProcState;
20555                enqueueUidChangeLocked(uidRec, -1, uidChange);
20556                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20557            }
20558        }
20559
20560        if (mProcessStats.shouldWriteNowLocked(now)) {
20561            mHandler.post(new Runnable() {
20562                @Override public void run() {
20563                    synchronized (ActivityManagerService.this) {
20564                        mProcessStats.writeStateAsyncLocked();
20565                    }
20566                }
20567            });
20568        }
20569
20570        if (DEBUG_OOM_ADJ) {
20571            final long duration = SystemClock.uptimeMillis() - now;
20572            if (false) {
20573                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20574                        new RuntimeException("here").fillInStackTrace());
20575            } else {
20576                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20577            }
20578        }
20579    }
20580
20581    final void idleUids() {
20582        synchronized (this) {
20583            final long nowElapsed = SystemClock.elapsedRealtime();
20584            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20585            long nextTime = 0;
20586            for (int i=mActiveUids.size()-1; i>=0; i--) {
20587                final UidRecord uidRec = mActiveUids.valueAt(i);
20588                final long bgTime = uidRec.lastBackgroundTime;
20589                if (bgTime > 0 && !uidRec.idle) {
20590                    if (bgTime <= maxBgTime) {
20591                        uidRec.idle = true;
20592                        doStopUidLocked(uidRec.uid, uidRec);
20593                    } else {
20594                        if (nextTime == 0 || nextTime > bgTime) {
20595                            nextTime = bgTime;
20596                        }
20597                    }
20598                }
20599            }
20600            if (nextTime > 0) {
20601                mHandler.removeMessages(IDLE_UIDS_MSG);
20602                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20603                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20604            }
20605        }
20606    }
20607
20608    final void runInBackgroundDisabled(int uid) {
20609        synchronized (this) {
20610            UidRecord uidRec = mActiveUids.get(uid);
20611            if (uidRec != null) {
20612                // This uid is actually running...  should it be considered background now?
20613                if (uidRec.idle) {
20614                    doStopUidLocked(uidRec.uid, uidRec);
20615                }
20616            } else {
20617                // This uid isn't actually running...  still send a report about it being "stopped".
20618                doStopUidLocked(uid, null);
20619            }
20620        }
20621    }
20622
20623    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20624        mServices.stopInBackgroundLocked(uid);
20625        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20626    }
20627
20628    final void trimApplications() {
20629        synchronized (this) {
20630            int i;
20631
20632            // First remove any unused application processes whose package
20633            // has been removed.
20634            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20635                final ProcessRecord app = mRemovedProcesses.get(i);
20636                if (app.activities.size() == 0
20637                        && app.curReceiver == null && app.services.size() == 0) {
20638                    Slog.i(
20639                        TAG, "Exiting empty application process "
20640                        + app.toShortString() + " ("
20641                        + (app.thread != null ? app.thread.asBinder() : null)
20642                        + ")\n");
20643                    if (app.pid > 0 && app.pid != MY_PID) {
20644                        app.kill("empty", false);
20645                    } else {
20646                        try {
20647                            app.thread.scheduleExit();
20648                        } catch (Exception e) {
20649                            // Ignore exceptions.
20650                        }
20651                    }
20652                    cleanUpApplicationRecordLocked(app, false, true, -1);
20653                    mRemovedProcesses.remove(i);
20654
20655                    if (app.persistent) {
20656                        addAppLocked(app.info, false, null /* ABI override */);
20657                    }
20658                }
20659            }
20660
20661            // Now update the oom adj for all processes.
20662            updateOomAdjLocked();
20663        }
20664    }
20665
20666    /** This method sends the specified signal to each of the persistent apps */
20667    public void signalPersistentProcesses(int sig) throws RemoteException {
20668        if (sig != Process.SIGNAL_USR1) {
20669            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20670        }
20671
20672        synchronized (this) {
20673            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20674                    != PackageManager.PERMISSION_GRANTED) {
20675                throw new SecurityException("Requires permission "
20676                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20677            }
20678
20679            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20680                ProcessRecord r = mLruProcesses.get(i);
20681                if (r.thread != null && r.persistent) {
20682                    Process.sendSignal(r.pid, sig);
20683                }
20684            }
20685        }
20686    }
20687
20688    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20689        if (proc == null || proc == mProfileProc) {
20690            proc = mProfileProc;
20691            profileType = mProfileType;
20692            clearProfilerLocked();
20693        }
20694        if (proc == null) {
20695            return;
20696        }
20697        try {
20698            proc.thread.profilerControl(false, null, profileType);
20699        } catch (RemoteException e) {
20700            throw new IllegalStateException("Process disappeared");
20701        }
20702    }
20703
20704    private void clearProfilerLocked() {
20705        if (mProfileFd != null) {
20706            try {
20707                mProfileFd.close();
20708            } catch (IOException e) {
20709            }
20710        }
20711        mProfileApp = null;
20712        mProfileProc = null;
20713        mProfileFile = null;
20714        mProfileType = 0;
20715        mAutoStopProfiler = false;
20716        mSamplingInterval = 0;
20717    }
20718
20719    public boolean profileControl(String process, int userId, boolean start,
20720            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20721
20722        try {
20723            synchronized (this) {
20724                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20725                // its own permission.
20726                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20727                        != PackageManager.PERMISSION_GRANTED) {
20728                    throw new SecurityException("Requires permission "
20729                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20730                }
20731
20732                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20733                    throw new IllegalArgumentException("null profile info or fd");
20734                }
20735
20736                ProcessRecord proc = null;
20737                if (process != null) {
20738                    proc = findProcessLocked(process, userId, "profileControl");
20739                }
20740
20741                if (start && (proc == null || proc.thread == null)) {
20742                    throw new IllegalArgumentException("Unknown process: " + process);
20743                }
20744
20745                if (start) {
20746                    stopProfilerLocked(null, 0);
20747                    setProfileApp(proc.info, proc.processName, profilerInfo);
20748                    mProfileProc = proc;
20749                    mProfileType = profileType;
20750                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20751                    try {
20752                        fd = fd.dup();
20753                    } catch (IOException e) {
20754                        fd = null;
20755                    }
20756                    profilerInfo.profileFd = fd;
20757                    proc.thread.profilerControl(start, profilerInfo, profileType);
20758                    fd = null;
20759                    mProfileFd = null;
20760                } else {
20761                    stopProfilerLocked(proc, profileType);
20762                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20763                        try {
20764                            profilerInfo.profileFd.close();
20765                        } catch (IOException e) {
20766                        }
20767                    }
20768                }
20769
20770                return true;
20771            }
20772        } catch (RemoteException e) {
20773            throw new IllegalStateException("Process disappeared");
20774        } finally {
20775            if (profilerInfo != null && profilerInfo.profileFd != null) {
20776                try {
20777                    profilerInfo.profileFd.close();
20778                } catch (IOException e) {
20779                }
20780            }
20781        }
20782    }
20783
20784    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20785        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20786                userId, true, ALLOW_FULL_ONLY, callName, null);
20787        ProcessRecord proc = null;
20788        try {
20789            int pid = Integer.parseInt(process);
20790            synchronized (mPidsSelfLocked) {
20791                proc = mPidsSelfLocked.get(pid);
20792            }
20793        } catch (NumberFormatException e) {
20794        }
20795
20796        if (proc == null) {
20797            ArrayMap<String, SparseArray<ProcessRecord>> all
20798                    = mProcessNames.getMap();
20799            SparseArray<ProcessRecord> procs = all.get(process);
20800            if (procs != null && procs.size() > 0) {
20801                proc = procs.valueAt(0);
20802                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20803                    for (int i=1; i<procs.size(); i++) {
20804                        ProcessRecord thisProc = procs.valueAt(i);
20805                        if (thisProc.userId == userId) {
20806                            proc = thisProc;
20807                            break;
20808                        }
20809                    }
20810                }
20811            }
20812        }
20813
20814        return proc;
20815    }
20816
20817    public boolean dumpHeap(String process, int userId, boolean managed,
20818            String path, ParcelFileDescriptor fd) throws RemoteException {
20819
20820        try {
20821            synchronized (this) {
20822                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20823                // its own permission (same as profileControl).
20824                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20825                        != PackageManager.PERMISSION_GRANTED) {
20826                    throw new SecurityException("Requires permission "
20827                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20828                }
20829
20830                if (fd == null) {
20831                    throw new IllegalArgumentException("null fd");
20832                }
20833
20834                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20835                if (proc == null || proc.thread == null) {
20836                    throw new IllegalArgumentException("Unknown process: " + process);
20837                }
20838
20839                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20840                if (!isDebuggable) {
20841                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20842                        throw new SecurityException("Process not debuggable: " + proc);
20843                    }
20844                }
20845
20846                proc.thread.dumpHeap(managed, path, fd);
20847                fd = null;
20848                return true;
20849            }
20850        } catch (RemoteException e) {
20851            throw new IllegalStateException("Process disappeared");
20852        } finally {
20853            if (fd != null) {
20854                try {
20855                    fd.close();
20856                } catch (IOException e) {
20857                }
20858            }
20859        }
20860    }
20861
20862    @Override
20863    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20864            String reportPackage) {
20865        if (processName != null) {
20866            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20867                    "setDumpHeapDebugLimit()");
20868        } else {
20869            synchronized (mPidsSelfLocked) {
20870                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20871                if (proc == null) {
20872                    throw new SecurityException("No process found for calling pid "
20873                            + Binder.getCallingPid());
20874                }
20875                if (!Build.IS_DEBUGGABLE
20876                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20877                    throw new SecurityException("Not running a debuggable build");
20878                }
20879                processName = proc.processName;
20880                uid = proc.uid;
20881                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20882                    throw new SecurityException("Package " + reportPackage + " is not running in "
20883                            + proc);
20884                }
20885            }
20886        }
20887        synchronized (this) {
20888            if (maxMemSize > 0) {
20889                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20890            } else {
20891                if (uid != 0) {
20892                    mMemWatchProcesses.remove(processName, uid);
20893                } else {
20894                    mMemWatchProcesses.getMap().remove(processName);
20895                }
20896            }
20897        }
20898    }
20899
20900    @Override
20901    public void dumpHeapFinished(String path) {
20902        synchronized (this) {
20903            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20904                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20905                        + " does not match last pid " + mMemWatchDumpPid);
20906                return;
20907            }
20908            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20909                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20910                        + " does not match last path " + mMemWatchDumpFile);
20911                return;
20912            }
20913            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20914            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20915        }
20916    }
20917
20918    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20919    public void monitor() {
20920        synchronized (this) { }
20921    }
20922
20923    void onCoreSettingsChange(Bundle settings) {
20924        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20925            ProcessRecord processRecord = mLruProcesses.get(i);
20926            try {
20927                if (processRecord.thread != null) {
20928                    processRecord.thread.setCoreSettings(settings);
20929                }
20930            } catch (RemoteException re) {
20931                /* ignore */
20932            }
20933        }
20934    }
20935
20936    // Multi-user methods
20937
20938    /**
20939     * Start user, if its not already running, but don't bring it to foreground.
20940     */
20941    @Override
20942    public boolean startUserInBackground(final int userId) {
20943        return mUserController.startUser(userId, /* foreground */ false);
20944    }
20945
20946    @Override
20947    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20948        return mUserController.unlockUser(userId, token, secret, listener);
20949    }
20950
20951    @Override
20952    public boolean switchUser(final int targetUserId) {
20953        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20954        UserInfo currentUserInfo;
20955        UserInfo targetUserInfo;
20956        synchronized (this) {
20957            int currentUserId = mUserController.getCurrentUserIdLocked();
20958            currentUserInfo = mUserController.getUserInfo(currentUserId);
20959            targetUserInfo = mUserController.getUserInfo(targetUserId);
20960            if (targetUserInfo == null) {
20961                Slog.w(TAG, "No user info for user #" + targetUserId);
20962                return false;
20963            }
20964            if (!targetUserInfo.supportsSwitchTo()) {
20965                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20966                return false;
20967            }
20968            if (targetUserInfo.isManagedProfile()) {
20969                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20970                return false;
20971            }
20972            mUserController.setTargetUserIdLocked(targetUserId);
20973        }
20974        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20975        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20976        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20977        return true;
20978    }
20979
20980    void scheduleStartProfilesLocked() {
20981        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20982            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20983                    DateUtils.SECOND_IN_MILLIS);
20984        }
20985    }
20986
20987    @Override
20988    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20989        return mUserController.stopUser(userId, force, callback);
20990    }
20991
20992    @Override
20993    public UserInfo getCurrentUser() {
20994        return mUserController.getCurrentUser();
20995    }
20996
20997    @Override
20998    public boolean isUserRunning(int userId, int flags) {
20999        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21000                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21001            String msg = "Permission Denial: isUserRunning() from pid="
21002                    + Binder.getCallingPid()
21003                    + ", uid=" + Binder.getCallingUid()
21004                    + " requires " + INTERACT_ACROSS_USERS;
21005            Slog.w(TAG, msg);
21006            throw new SecurityException(msg);
21007        }
21008        synchronized (this) {
21009            return mUserController.isUserRunningLocked(userId, flags);
21010        }
21011    }
21012
21013    @Override
21014    public int[] getRunningUserIds() {
21015        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21016                != PackageManager.PERMISSION_GRANTED) {
21017            String msg = "Permission Denial: isUserRunning() from pid="
21018                    + Binder.getCallingPid()
21019                    + ", uid=" + Binder.getCallingUid()
21020                    + " requires " + INTERACT_ACROSS_USERS;
21021            Slog.w(TAG, msg);
21022            throw new SecurityException(msg);
21023        }
21024        synchronized (this) {
21025            return mUserController.getStartedUserArrayLocked();
21026        }
21027    }
21028
21029    @Override
21030    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21031        mUserController.registerUserSwitchObserver(observer);
21032    }
21033
21034    @Override
21035    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21036        mUserController.unregisterUserSwitchObserver(observer);
21037    }
21038
21039    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21040        if (info == null) return null;
21041        ApplicationInfo newInfo = new ApplicationInfo(info);
21042        newInfo.initForUser(userId);
21043        return newInfo;
21044    }
21045
21046    public boolean isUserStopped(int userId) {
21047        synchronized (this) {
21048            return mUserController.getStartedUserStateLocked(userId) == null;
21049        }
21050    }
21051
21052    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21053        if (aInfo == null
21054                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21055            return aInfo;
21056        }
21057
21058        ActivityInfo info = new ActivityInfo(aInfo);
21059        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21060        return info;
21061    }
21062
21063    private boolean processSanityChecksLocked(ProcessRecord process) {
21064        if (process == null || process.thread == null) {
21065            return false;
21066        }
21067
21068        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21069        if (!isDebuggable) {
21070            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21071                return false;
21072            }
21073        }
21074
21075        return true;
21076    }
21077
21078    public boolean startBinderTracking() throws RemoteException {
21079        synchronized (this) {
21080            mBinderTransactionTrackingEnabled = true;
21081            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21082            // permission (same as profileControl).
21083            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21084                    != PackageManager.PERMISSION_GRANTED) {
21085                throw new SecurityException("Requires permission "
21086                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21087            }
21088
21089            for (int i = 0; i < mLruProcesses.size(); i++) {
21090                ProcessRecord process = mLruProcesses.get(i);
21091                if (!processSanityChecksLocked(process)) {
21092                    continue;
21093                }
21094                try {
21095                    process.thread.startBinderTracking();
21096                } catch (RemoteException e) {
21097                    Log.v(TAG, "Process disappared");
21098                }
21099            }
21100            return true;
21101        }
21102    }
21103
21104    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21105        try {
21106            synchronized (this) {
21107                mBinderTransactionTrackingEnabled = false;
21108                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21109                // permission (same as profileControl).
21110                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21111                        != PackageManager.PERMISSION_GRANTED) {
21112                    throw new SecurityException("Requires permission "
21113                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21114                }
21115
21116                if (fd == null) {
21117                    throw new IllegalArgumentException("null fd");
21118                }
21119
21120                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21121                pw.println("Binder transaction traces for all processes.\n");
21122                for (ProcessRecord process : mLruProcesses) {
21123                    if (!processSanityChecksLocked(process)) {
21124                        continue;
21125                    }
21126
21127                    pw.println("Traces for process: " + process.processName);
21128                    pw.flush();
21129                    try {
21130                        TransferPipe tp = new TransferPipe();
21131                        try {
21132                            process.thread.stopBinderTrackingAndDump(
21133                                    tp.getWriteFd().getFileDescriptor());
21134                            tp.go(fd.getFileDescriptor());
21135                        } finally {
21136                            tp.kill();
21137                        }
21138                    } catch (IOException e) {
21139                        pw.println("Failure while dumping IPC traces from " + process +
21140                                ".  Exception: " + e);
21141                        pw.flush();
21142                    } catch (RemoteException e) {
21143                        pw.println("Got a RemoteException while dumping IPC traces from " +
21144                                process + ".  Exception: " + e);
21145                        pw.flush();
21146                    }
21147                }
21148                fd = null;
21149                return true;
21150            }
21151        } finally {
21152            if (fd != null) {
21153                try {
21154                    fd.close();
21155                } catch (IOException e) {
21156                }
21157            }
21158        }
21159    }
21160
21161    private final class LocalService extends ActivityManagerInternal {
21162        @Override
21163        public void onWakefulnessChanged(int wakefulness) {
21164            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21165        }
21166
21167        @Override
21168        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21169                String processName, String abiOverride, int uid, Runnable crashHandler) {
21170            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21171                    processName, abiOverride, uid, crashHandler);
21172        }
21173
21174        @Override
21175        public SleepToken acquireSleepToken(String tag) {
21176            Preconditions.checkNotNull(tag);
21177
21178            synchronized (ActivityManagerService.this) {
21179                SleepTokenImpl token = new SleepTokenImpl(tag);
21180                mSleepTokens.add(token);
21181                updateSleepIfNeededLocked();
21182                applyVrModeIfNeededLocked(mFocusedActivity, false);
21183                return token;
21184            }
21185        }
21186
21187        @Override
21188        public ComponentName getHomeActivityForUser(int userId) {
21189            synchronized (ActivityManagerService.this) {
21190                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21191                return homeActivity == null ? null : homeActivity.realActivity;
21192            }
21193        }
21194
21195        @Override
21196        public void onUserRemoved(int userId) {
21197            synchronized (ActivityManagerService.this) {
21198                ActivityManagerService.this.onUserStoppedLocked(userId);
21199            }
21200        }
21201
21202        @Override
21203        public void onLocalVoiceInteractionStarted(IBinder activity,
21204                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21205            synchronized (ActivityManagerService.this) {
21206                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21207                        voiceSession, voiceInteractor);
21208            }
21209        }
21210
21211        @Override
21212        public void notifyStartingWindowDrawn() {
21213            synchronized (ActivityManagerService.this) {
21214                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21215            }
21216        }
21217
21218        @Override
21219        public void notifyAppTransitionStarting(int reason) {
21220            synchronized (ActivityManagerService.this) {
21221                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21222            }
21223        }
21224
21225        @Override
21226        public void notifyAppTransitionFinished() {
21227            synchronized (ActivityManagerService.this) {
21228                mStackSupervisor.notifyAppTransitionDone();
21229            }
21230        }
21231
21232        @Override
21233        public void notifyAppTransitionCancelled() {
21234            synchronized (ActivityManagerService.this) {
21235                mStackSupervisor.notifyAppTransitionDone();
21236            }
21237        }
21238
21239        @Override
21240        public List<IBinder> getTopVisibleActivities() {
21241            synchronized (ActivityManagerService.this) {
21242                return mStackSupervisor.getTopVisibleActivities();
21243            }
21244        }
21245
21246        @Override
21247        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21248            synchronized (ActivityManagerService.this) {
21249                mStackSupervisor.setDockedStackMinimized(minimized);
21250            }
21251        }
21252
21253        @Override
21254        public void killForegroundAppsForUser(int userHandle) {
21255            synchronized (ActivityManagerService.this) {
21256                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21257                final int NP = mProcessNames.getMap().size();
21258                for (int ip = 0; ip < NP; ip++) {
21259                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21260                    final int NA = apps.size();
21261                    for (int ia = 0; ia < NA; ia++) {
21262                        final ProcessRecord app = apps.valueAt(ia);
21263                        if (app.persistent) {
21264                            // We don't kill persistent processes.
21265                            continue;
21266                        }
21267                        if (app.removed) {
21268                            procs.add(app);
21269                        } else if (app.userId == userHandle && app.foregroundActivities) {
21270                            app.removed = true;
21271                            procs.add(app);
21272                        }
21273                    }
21274                }
21275
21276                final int N = procs.size();
21277                for (int i = 0; i < N; i++) {
21278                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21279                }
21280            }
21281        }
21282    }
21283
21284    private final class SleepTokenImpl extends SleepToken {
21285        private final String mTag;
21286        private final long mAcquireTime;
21287
21288        public SleepTokenImpl(String tag) {
21289            mTag = tag;
21290            mAcquireTime = SystemClock.uptimeMillis();
21291        }
21292
21293        @Override
21294        public void release() {
21295            synchronized (ActivityManagerService.this) {
21296                if (mSleepTokens.remove(this)) {
21297                    updateSleepIfNeededLocked();
21298                }
21299            }
21300        }
21301
21302        @Override
21303        public String toString() {
21304            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21305        }
21306    }
21307
21308    /**
21309     * An implementation of IAppTask, that allows an app to manage its own tasks via
21310     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21311     * only the process that calls getAppTasks() can call the AppTask methods.
21312     */
21313    class AppTaskImpl extends IAppTask.Stub {
21314        private int mTaskId;
21315        private int mCallingUid;
21316
21317        public AppTaskImpl(int taskId, int callingUid) {
21318            mTaskId = taskId;
21319            mCallingUid = callingUid;
21320        }
21321
21322        private void checkCaller() {
21323            if (mCallingUid != Binder.getCallingUid()) {
21324                throw new SecurityException("Caller " + mCallingUid
21325                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21326            }
21327        }
21328
21329        @Override
21330        public void finishAndRemoveTask() {
21331            checkCaller();
21332
21333            synchronized (ActivityManagerService.this) {
21334                long origId = Binder.clearCallingIdentity();
21335                try {
21336                    // We remove the task from recents to preserve backwards
21337                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21338                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21339                    }
21340                } finally {
21341                    Binder.restoreCallingIdentity(origId);
21342                }
21343            }
21344        }
21345
21346        @Override
21347        public ActivityManager.RecentTaskInfo getTaskInfo() {
21348            checkCaller();
21349
21350            synchronized (ActivityManagerService.this) {
21351                long origId = Binder.clearCallingIdentity();
21352                try {
21353                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21354                    if (tr == null) {
21355                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21356                    }
21357                    return createRecentTaskInfoFromTaskRecord(tr);
21358                } finally {
21359                    Binder.restoreCallingIdentity(origId);
21360                }
21361            }
21362        }
21363
21364        @Override
21365        public void moveToFront() {
21366            checkCaller();
21367            // Will bring task to front if it already has a root activity.
21368            final long origId = Binder.clearCallingIdentity();
21369            try {
21370                synchronized (this) {
21371                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21372                }
21373            } finally {
21374                Binder.restoreCallingIdentity(origId);
21375            }
21376        }
21377
21378        @Override
21379        public int startActivity(IBinder whoThread, String callingPackage,
21380                Intent intent, String resolvedType, Bundle bOptions) {
21381            checkCaller();
21382
21383            int callingUser = UserHandle.getCallingUserId();
21384            TaskRecord tr;
21385            IApplicationThread appThread;
21386            synchronized (ActivityManagerService.this) {
21387                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21388                if (tr == null) {
21389                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21390                }
21391                appThread = ApplicationThreadNative.asInterface(whoThread);
21392                if (appThread == null) {
21393                    throw new IllegalArgumentException("Bad app thread " + appThread);
21394                }
21395            }
21396            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21397                    resolvedType, null, null, null, null, 0, 0, null, null,
21398                    null, bOptions, false, callingUser, null, tr);
21399        }
21400
21401        @Override
21402        public void setExcludeFromRecents(boolean exclude) {
21403            checkCaller();
21404
21405            synchronized (ActivityManagerService.this) {
21406                long origId = Binder.clearCallingIdentity();
21407                try {
21408                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21409                    if (tr == null) {
21410                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21411                    }
21412                    Intent intent = tr.getBaseIntent();
21413                    if (exclude) {
21414                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21415                    } else {
21416                        intent.setFlags(intent.getFlags()
21417                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21418                    }
21419                } finally {
21420                    Binder.restoreCallingIdentity(origId);
21421                }
21422            }
21423        }
21424    }
21425
21426    /**
21427     * Kill processes for the user with id userId and that depend on the package named packageName
21428     */
21429    @Override
21430    public void killPackageDependents(String packageName, int userId) {
21431        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21432        if (packageName == null) {
21433            throw new NullPointerException(
21434                    "Cannot kill the dependents of a package without its name.");
21435        }
21436
21437        long callingId = Binder.clearCallingIdentity();
21438        IPackageManager pm = AppGlobals.getPackageManager();
21439        int pkgUid = -1;
21440        try {
21441            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21442        } catch (RemoteException e) {
21443        }
21444        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21445            throw new IllegalArgumentException(
21446                    "Cannot kill dependents of non-existing package " + packageName);
21447        }
21448        try {
21449            synchronized(this) {
21450                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21451                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21452                        "dep: " + packageName);
21453            }
21454        } finally {
21455            Binder.restoreCallingIdentity(callingId);
21456        }
21457    }
21458}
21459